wolfhece 2.2.35__py3-none-any.whl → 2.2.37__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 +50 -0
- wolfhece/PyVertexvectors.py +883 -488
- wolfhece/analyze_poly.py +1 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/picc.py +38 -4
- wolfhece/pydownloader.py +1 -0
- {wolfhece-2.2.35.dist-info → wolfhece-2.2.37.dist-info}/METADATA +1 -1
- {wolfhece-2.2.35.dist-info → wolfhece-2.2.37.dist-info}/RECORD +11 -11
- {wolfhece-2.2.35.dist-info → wolfhece-2.2.37.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.35.dist-info → wolfhece-2.2.37.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.35.dist-info → wolfhece-2.2.37.dist-info}/top_level.txt +0 -0
wolfhece/PyVertexvectors.py
CHANGED
@@ -28,6 +28,7 @@ from matplotlib.figure import Figure
|
|
28
28
|
from matplotlib import cm
|
29
29
|
from matplotlib.colors import Colormap
|
30
30
|
from matplotlib.tri import Triangulation as mpl_tri
|
31
|
+
import warnings
|
31
32
|
|
32
33
|
import struct
|
33
34
|
import pyvista as pv
|
@@ -66,13 +67,17 @@ class Triangulation(Element_To_Draw):
|
|
66
67
|
super().__init__(idx, plotted, mapviewer, need_for_wx)
|
67
68
|
|
68
69
|
self.filename = ''
|
70
|
+
|
69
71
|
self.tri= tri
|
70
72
|
self.pts = pts
|
73
|
+
|
71
74
|
self.id_list = -99999
|
72
75
|
|
73
76
|
self.nb_tri = len(tri)
|
74
77
|
self.nb_pts = len(pts)
|
75
78
|
|
79
|
+
self._used_tri = [True] * self.nb_tri
|
80
|
+
|
76
81
|
self._move_start = None
|
77
82
|
self._move_step = None # step for a move
|
78
83
|
self._rotation_center = None
|
@@ -408,10 +413,17 @@ class Triangulation(Element_To_Draw):
|
|
408
413
|
else:
|
409
414
|
glCallList(self.id_list)
|
410
415
|
|
411
|
-
def plot_matplotlib(self, ax:Axes, color='black', alpha=1., lw=1.5, **kwargs):
|
416
|
+
def plot_matplotlib(self, ax:Axes | tuple[Figure, Axes] = None, color='black', alpha=1., lw=1.5, **kwargs):
|
412
417
|
""" Plot the triangulation in Matplotlib
|
413
418
|
"""
|
414
419
|
|
420
|
+
if isinstance(ax, tuple):
|
421
|
+
fig, ax = ax
|
422
|
+
elif ax is None:
|
423
|
+
fig, ax = plt.subplots()
|
424
|
+
else:
|
425
|
+
fig = ax.figure
|
426
|
+
|
415
427
|
if self.nb_tri>0:
|
416
428
|
for curtri in self.tri:
|
417
429
|
x = [self.pts[curtri[0]][0], self.pts[curtri[1]][0], self.pts[curtri[2]][0], self.pts[curtri[0]][0]]
|
@@ -420,6 +432,8 @@ class Triangulation(Element_To_Draw):
|
|
420
432
|
else:
|
421
433
|
logging.warning('No triangles to plot')
|
422
434
|
|
435
|
+
return fig, ax
|
436
|
+
|
423
437
|
@property
|
424
438
|
def mpl_triangulation(self) -> mpl_tri:
|
425
439
|
""" Return the triangulation as a Matplotlib Triangulation object """
|
@@ -429,13 +443,24 @@ class Triangulation(Element_To_Draw):
|
|
429
443
|
logging.warning('No triangles to plot')
|
430
444
|
return None
|
431
445
|
|
432
|
-
def plot_matplotlib_3D(self, ax:Axes, color='black', alpha=0.2, lw=1.5, edgecolor='k', shade=True, **kwargs):
|
446
|
+
def plot_matplotlib_3D(self, ax:Axes | tuple[Figure, Axes] = None, color='black', alpha=0.2, lw=1.5, edgecolor='k', shade=True, **kwargs):
|
433
447
|
""" Plot the triangulation in Matplotlib 3D
|
434
448
|
"""
|
449
|
+
|
435
450
|
if self.nb_tri>0:
|
451
|
+
if isinstance(ax, tuple):
|
452
|
+
fig, ax = ax
|
453
|
+
elif ax is None:
|
454
|
+
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
|
455
|
+
else:
|
456
|
+
fig = ax.figure
|
457
|
+
|
436
458
|
ax.plot_trisurf(self.mpl_triangulation, Z=self.pts[:,2], color=color, alpha=alpha, lw=lw, edgecolor=edgecolor, shade=shade, **kwargs)
|
459
|
+
|
460
|
+
return fig, ax
|
437
461
|
else:
|
438
462
|
logging.warning('No triangles to plot')
|
463
|
+
return None, None
|
439
464
|
|
440
465
|
def find_minmax(self,force):
|
441
466
|
""" Find the min and max of the triangulation
|
@@ -550,6 +575,45 @@ class Triangulation(Element_To_Draw):
|
|
550
575
|
angle = np.round(angle/self._rotation_step)*self._rotation_step
|
551
576
|
|
552
577
|
return self.rotate(-angle, center=self._rotation_center, use_cache=use_cache)
|
578
|
+
|
579
|
+
def _get_polygons(self) -> list[Polygon]:
|
580
|
+
""" Get the polygons from the triangulation """
|
581
|
+
polygons = []
|
582
|
+
for curtri in self.tri:
|
583
|
+
if len(curtri) == 3:
|
584
|
+
poly = Polygon([self.pts[curtri[0]][:2], self.pts[curtri[1]][:2], self.pts[curtri[2]][:2]])
|
585
|
+
if poly.is_valid:
|
586
|
+
polygons.append(poly)
|
587
|
+
else:
|
588
|
+
logging.warning('Invalid polygon found in triangulation: {}'.format(poly))
|
589
|
+
else:
|
590
|
+
logging.warning('Triangle with {} vertices found in triangulation: {}'.format(len(curtri), curtri))
|
591
|
+
return polygons
|
592
|
+
|
593
|
+
def unuse_triangles_containing_points(self, points:list[Point]):
|
594
|
+
""" Unuse triangles containing points """
|
595
|
+
|
596
|
+
polys = self._get_polygons()
|
597
|
+
for point in points:
|
598
|
+
for i, poly in enumerate(polys):
|
599
|
+
if poly.contains(point):
|
600
|
+
self._used_tri[i] = False
|
601
|
+
|
602
|
+
def get_triangles_as_listwolfvertices(self, used_only:bool=True) -> list[list[wolfvertex]]:
|
603
|
+
""" Get the triangles as a list of wolfvertex objects """
|
604
|
+
|
605
|
+
triangles = []
|
606
|
+
for i, curtri in enumerate(self.tri):
|
607
|
+
if not used_only or (used_only and self._used_tri[i]):
|
608
|
+
if len(curtri) == 3:
|
609
|
+
v1 = wolfvertex(self.pts[curtri[0]][0], self.pts[curtri[0]][1], self.pts[curtri[0]][2])
|
610
|
+
v2 = wolfvertex(self.pts[curtri[1]][0], self.pts[curtri[1]][1], self.pts[curtri[1]][2])
|
611
|
+
v3 = wolfvertex(self.pts[curtri[2]][0], self.pts[curtri[2]][1], self.pts[curtri[2]][2])
|
612
|
+
triangles.append([v1, v2, v3])
|
613
|
+
else:
|
614
|
+
logging.warning('Triangle with {} vertices found in triangulation: {}'.format(len(curtri), curtri))
|
615
|
+
return triangles
|
616
|
+
|
553
617
|
class vectorproperties:
|
554
618
|
""" Vector properties """
|
555
619
|
used:bool
|
@@ -2212,6 +2276,81 @@ class vector:
|
|
2212
2276
|
|
2213
2277
|
return len(not_in_use) > 0
|
2214
2278
|
|
2279
|
+
def check_if_interior_exists(self):
|
2280
|
+
""" Check if the vector has an interior and adapt in_use accordingly.
|
2281
|
+
|
2282
|
+
The verification is only made in 2D, as the interior is defined as a pair of segments that correspond exactly to the same coordinates.
|
2283
|
+
Z coordinates are not taken into account in this verification.
|
2284
|
+
|
2285
|
+
"""
|
2286
|
+
|
2287
|
+
xy = self.xy
|
2288
|
+
if self.closed and (xy[0,0] == xy[-1,0] and xy[0,1] == xy[-1,1]):
|
2289
|
+
# If the vector is closed, we remove the last vertex to avoid checking it
|
2290
|
+
xy = xy[:-1]
|
2291
|
+
|
2292
|
+
xy_unique, inverse, count = np.unique(xy, return_inverse=True, return_counts=True, axis=0)
|
2293
|
+
|
2294
|
+
duplicate_found = False
|
2295
|
+
|
2296
|
+
if xy.shape[0] != xy_unique.shape[0]:
|
2297
|
+
# There are duplicates, we need to test if the duplicate form a segment
|
2298
|
+
|
2299
|
+
# Find the duplicate indices
|
2300
|
+
duplicate_indices = np.where(count > 1)[0]
|
2301
|
+
# Find the inverse indices of the duplicates
|
2302
|
+
duplicate_indices = np.where(np.isin(inverse, duplicate_indices))[0]
|
2303
|
+
diff = np.diff(duplicate_indices)
|
2304
|
+
|
2305
|
+
for i in range(len(diff)):
|
2306
|
+
# Set the in_use property to False for the vertices that are not used
|
2307
|
+
if diff[i] == 1:
|
2308
|
+
self.myvertices[duplicate_indices[i+1]].in_use = False
|
2309
|
+
duplicate_found = True
|
2310
|
+
|
2311
|
+
if duplicate_found:
|
2312
|
+
self.reset_linestring()
|
2313
|
+
self._reset_listogl()
|
2314
|
+
|
2315
|
+
|
2316
|
+
@property
|
2317
|
+
def nb_interiors(self) -> int:
|
2318
|
+
""" Return the number of interiors in the vector.
|
2319
|
+
|
2320
|
+
If the vector is filled, it returns the number of pairs of vertices not in use.
|
2321
|
+
If the vector is not filled, it returns the number of vertices not in use.
|
2322
|
+
"""
|
2323
|
+
not_in_use = [curvert for curvert in self.myvertices if not curvert.in_use]
|
2324
|
+
|
2325
|
+
return len(not_in_use) // 2 if self.myprop.filled else len(not_in_use)
|
2326
|
+
|
2327
|
+
@property
|
2328
|
+
def _parts(self) -> "zone":
|
2329
|
+
""" Return the parts of the vector as a zone.
|
2330
|
+
|
2331
|
+
Useful for creating subpolygons or triangulation.
|
2332
|
+
"""
|
2333
|
+
self.find_minmax()
|
2334
|
+
|
2335
|
+
parts = zone()
|
2336
|
+
current_part = vector()
|
2337
|
+
for curvert in self.myvertices:
|
2338
|
+
if curvert.in_use:
|
2339
|
+
current_part.add_vertex(curvert)
|
2340
|
+
else:
|
2341
|
+
if current_part.nbvertices > 0:
|
2342
|
+
if parts.nbvectors > 0:
|
2343
|
+
current_part.force_to_close()
|
2344
|
+
parts.add_vector(current_part)
|
2345
|
+
current_part = vector()
|
2346
|
+
|
2347
|
+
for curvert in current_part.myvertices:
|
2348
|
+
parts.myvectors[0].add_vertex(curvert)
|
2349
|
+
|
2350
|
+
parts.myvectors[0].force_to_close()
|
2351
|
+
|
2352
|
+
return parts
|
2353
|
+
|
2215
2354
|
def get_subpolygons(self) -> list[list[wolfvertex]]:
|
2216
2355
|
"""
|
2217
2356
|
Return a list of polygons from the vector
|
@@ -2223,10 +2362,41 @@ class vector:
|
|
2223
2362
|
return []
|
2224
2363
|
|
2225
2364
|
if self.myprop.filled:
|
2226
|
-
if self.
|
2227
|
-
|
2365
|
+
if self.has_interior:
|
2366
|
+
#En attendant de lier WOLF-Fortran, on utilise la triangulation contrainte de la librairie Triangle -- https://rufat.be/triangle/
|
2367
|
+
|
2368
|
+
parts = self._parts
|
2369
|
+
tri = parts.create_constrainedDelaunay(nb = 0)
|
2370
|
+
centroid_interiors = [part.centroid for part in parts.myvectors[1:]]
|
2371
|
+
tri.unuse_triangles_containing_points(centroid_interiors)
|
2372
|
+
|
2373
|
+
return tri.get_triangles_as_listwolfvertices()
|
2374
|
+
|
2228
2375
|
else:
|
2229
|
-
|
2376
|
+
# if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
|
2377
|
+
# return [self.myvertices + [self.myvertices[0]]]
|
2378
|
+
# else:
|
2379
|
+
# return [self.myvertices]
|
2380
|
+
xx, yy = self.polygon.exterior.xy
|
2381
|
+
|
2382
|
+
# On translate les coordonnées pour éviter les erreurs de triangulation
|
2383
|
+
tr_x = np.array(xx).min()
|
2384
|
+
tr_y = np.array(yy).min()
|
2385
|
+
|
2386
|
+
xx = np.array(xx)-tr_x
|
2387
|
+
yy = np.array(yy)-tr_y
|
2388
|
+
|
2389
|
+
geom = {'vertices' : [[x,y] for x,y in zip(xx[:-1],yy[:-1])], 'segments' : [[i,i+1] for i in range(len(xx)-2)]+[[len(xx)-2,0]]}
|
2390
|
+
|
2391
|
+
try:
|
2392
|
+
delaunay = triangle.triangulate(geom, 'p')
|
2393
|
+
tri = []
|
2394
|
+
for curtri in delaunay['triangles']:
|
2395
|
+
# on traduit les coordonnées pour revenir dans le monde réel
|
2396
|
+
tri.append([wolfvertex(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y) for i in range(3)])
|
2397
|
+
return tri
|
2398
|
+
except:
|
2399
|
+
pass
|
2230
2400
|
|
2231
2401
|
else:
|
2232
2402
|
if self.has_interior:
|
@@ -2396,28 +2566,35 @@ class vector:
|
|
2396
2566
|
logging.debug(_('Polygon not in Polygon'))
|
2397
2567
|
|
2398
2568
|
else:
|
2399
|
-
#En attendant de lier WOLF-Fortran, on utilise la triangulation contrainte de la librairie Triangle -- https://rufat.be/triangle/
|
2400
|
-
xx, yy = ls.exterior.xy
|
2401
|
-
|
2402
|
-
# On translate les coordonnées pour éviter les erreurs de triangulation
|
2403
|
-
tr_x = np.array(xx).min()
|
2404
|
-
tr_y = np.array(yy).min()
|
2405
|
-
|
2406
|
-
xx = np.array(xx)-tr_x
|
2407
|
-
yy = np.array(yy)-tr_y
|
2408
|
-
|
2409
|
-
geom = {'vertices' : [[x,y] for x,y in zip(xx[:-1],yy[:-1])], 'segments' : [[i,i+1] for i in range(len(xx)-2)]+[[len(xx)-2,0]]}
|
2410
|
-
|
2411
|
-
try:
|
2412
|
-
|
2413
|
-
|
2414
|
-
|
2415
|
-
|
2416
|
-
|
2417
|
-
|
2418
|
-
|
2419
|
-
except:
|
2420
|
-
|
2569
|
+
# #En attendant de lier WOLF-Fortran, on utilise la triangulation contrainte de la librairie Triangle -- https://rufat.be/triangle/
|
2570
|
+
# xx, yy = ls.exterior.xy
|
2571
|
+
|
2572
|
+
# # On translate les coordonnées pour éviter les erreurs de triangulation
|
2573
|
+
# tr_x = np.array(xx).min()
|
2574
|
+
# tr_y = np.array(yy).min()
|
2575
|
+
|
2576
|
+
# xx = np.array(xx)-tr_x
|
2577
|
+
# yy = np.array(yy)-tr_y
|
2578
|
+
|
2579
|
+
# geom = {'vertices' : [[x,y] for x,y in zip(xx[:-1],yy[:-1])], 'segments' : [[i,i+1] for i in range(len(xx)-2)]+[[len(xx)-2,0]]}
|
2580
|
+
|
2581
|
+
# try:
|
2582
|
+
# delaunay = triangle.triangulate(geom, 'p')
|
2583
|
+
# for curtri in delaunay['triangles']:
|
2584
|
+
# glBegin(GL_POLYGON)
|
2585
|
+
# for i in range(3):
|
2586
|
+
# # on retraduit les coordonnées pour revenir dans le monde réel
|
2587
|
+
# glVertex2d(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y)
|
2588
|
+
# glEnd()
|
2589
|
+
# except:
|
2590
|
+
# pass
|
2591
|
+
|
2592
|
+
all_polys = self.get_subpolygons()
|
2593
|
+
for curpoly in all_polys:
|
2594
|
+
glBegin(GL_POLYGON)
|
2595
|
+
for curvertex in curpoly:
|
2596
|
+
glVertex2d(curvertex.x, curvertex.y)
|
2597
|
+
glEnd()
|
2421
2598
|
|
2422
2599
|
else:
|
2423
2600
|
all_polys = self.get_subpolygons()
|
@@ -2488,19 +2665,32 @@ class vector:
|
|
2488
2665
|
else:
|
2489
2666
|
logging.warning(_('No image texture available for plot'))
|
2490
2667
|
|
2491
|
-
def plot_matplotlib(self, ax:plt.Axes):
|
2668
|
+
def plot_matplotlib(self, ax:plt.Axes | tuple[Figure, Axes] = None):
|
2492
2669
|
"""
|
2493
|
-
Plot Matplotlib
|
2670
|
+
Plot Matplotlib - XY coordinates ONLY
|
2671
|
+
|
2672
|
+
:param ax: Matplotlib Axes to plot on or a tuple (fig, ax) where fig is the figure and ax is the axes.
|
2673
|
+
If ax is None, a new figure and axes will be created.
|
2494
2674
|
"""
|
2495
2675
|
|
2676
|
+
if isinstance(ax, tuple):
|
2677
|
+
# if ax is a tuple, we assume it is (fig, ax)
|
2678
|
+
fig, ax = ax
|
2679
|
+
elif ax is None:
|
2680
|
+
fig, ax = plt.subplots()
|
2681
|
+
else:
|
2682
|
+
fig = ax.figure
|
2683
|
+
|
2496
2684
|
if self.myprop.used:
|
2497
2685
|
|
2498
2686
|
if self.myprop.filled:
|
2499
2687
|
rgb=getRGBfromI(self.myprop.color)
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2688
|
+
subpoly = self.get_subpolygons()
|
2689
|
+
for curpoly in subpoly:
|
2690
|
+
if self.myprop.transparent:
|
2691
|
+
ax.fill([curvert.x for curvert in curpoly], [curvert.y for curvert in curpoly], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.,self.myprop.alpha))
|
2692
|
+
else:
|
2693
|
+
ax.fill([curvert.x for curvert in curpoly], [curvert.y for curvert in curpoly], color=(rgb[0]/255.,rgb[1]/255.,rgb[2]/255.))
|
2504
2694
|
else:
|
2505
2695
|
rgb=getRGBfromI(self.myprop.color)
|
2506
2696
|
subpoly = self.get_subpolygons()
|
@@ -2512,164 +2702,438 @@ class vector:
|
|
2512
2702
|
|
2513
2703
|
self.plot_legend_mpl(ax)
|
2514
2704
|
|
2515
|
-
|
2516
|
-
""" Retunr a 'Text_Infos' instance for the legend """
|
2517
|
-
|
2518
|
-
r,g,b = getRGBfromI(self.myprop.legendcolor)
|
2519
|
-
tinfos = Text_Infos(self.myprop.legendpriority,
|
2520
|
-
(np.cos(self.myprop.legendorientation/180*np.pi),
|
2521
|
-
np.sin(self.myprop.legendorientation/180*np.pi)),
|
2522
|
-
self.myprop.legendfontname,
|
2523
|
-
self.myprop.legendfontsize,
|
2524
|
-
colour=(r,g,b,255),
|
2525
|
-
dimsreal=(self.myprop.legendlength,
|
2526
|
-
self.myprop.legendheight),
|
2527
|
-
relative_position=self.myprop.legendrelpos)
|
2705
|
+
return fig, ax
|
2528
2706
|
|
2529
|
-
|
2707
|
+
def plot_matplotlib_sz(self, ax:plt.Axes | tuple[Figure, Axes] = None):
|
2708
|
+
"""
|
2709
|
+
Plot Matplotlib - SZ coordinates ONLY.
|
2530
2710
|
|
2531
|
-
|
2532
|
-
""" Retunr a 'Text_Infos' instance for the legend """
|
2711
|
+
S is the curvilinear abscissa, Z is the elevation.
|
2533
2712
|
|
2534
|
-
|
2535
|
-
|
2536
|
-
|
2537
|
-
self.myprop.legendfontname,
|
2538
|
-
12,
|
2539
|
-
colour=(r,g,b,255),
|
2540
|
-
dimsreal=(self.myprop.legendlength,
|
2541
|
-
self.myprop.legendheight),
|
2542
|
-
relative_position=7)
|
2713
|
+
:param ax: Matplotlib Axes to plot on or a tuple (fig, ax) where fig is the figure and ax is the axes.
|
2714
|
+
If ax is None, a new figure and axes will be created.
|
2715
|
+
"""
|
2543
2716
|
|
2544
|
-
|
2717
|
+
if isinstance(ax, tuple):
|
2718
|
+
# if ax is a tuple, we assume it is (fig, ax)
|
2719
|
+
fig, ax = ax
|
2720
|
+
elif ax is None:
|
2721
|
+
fig, ax = plt.subplots()
|
2722
|
+
else:
|
2723
|
+
fig = ax.figure
|
2545
2724
|
|
2546
|
-
def add2tree(self, tree:TreeListCtrl, root):
|
2547
|
-
"""
|
2548
|
-
Ajout de l'objte à un TreeListCtrl wx
|
2549
|
-
"""
|
2550
|
-
self.mytree=tree
|
2551
|
-
self.myitem=tree.AppendItem(root, self.myname,data=self)
|
2552
2725
|
if self.myprop.used:
|
2553
|
-
|
2726
|
+
s,z = self.sz_curvi
|
2554
2727
|
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
if self.mytree is not None:
|
2561
|
-
self.mytree.UncheckItem(self.myitem)
|
2728
|
+
rgb=getRGBfromI(self.myprop.color)
|
2729
|
+
if self.myprop.transparent:
|
2730
|
+
ax.plot(s, z, color=(rgb[0]/255., rgb[1]/255., rgb[2]/255., self.myprop.alpha), linewidth=self.myprop.width)
|
2731
|
+
else:
|
2732
|
+
ax.plot(s, z, color=(rgb[0]/255., rgb[1]/255., rgb[2]/255.), linewidth=self.myprop.width)
|
2562
2733
|
|
2563
|
-
|
2734
|
+
return fig, ax
|
2564
2735
|
|
2565
|
-
def
|
2736
|
+
def plot_linked(self, fig, ax, linked_arrays:dict):
|
2566
2737
|
"""
|
2567
|
-
|
2738
|
+
Graphique Matplolib de valeurs dans les matrices liées
|
2568
2739
|
"""
|
2569
|
-
|
2570
|
-
|
2571
|
-
self.mytree.CheckItem(self.myitem)
|
2572
|
-
|
2740
|
+
# from .wolf_array import WolfArray
|
2741
|
+
# from .wolfresults_2D import Wolfresults_2D
|
2573
2742
|
|
2574
|
-
|
2743
|
+
colors=['red','blue','green']
|
2575
2744
|
|
2576
|
-
|
2577
|
-
|
2578
|
-
|
2579
|
-
|
2580
|
-
curv:wolfvertex
|
2745
|
+
exit=True
|
2746
|
+
for curlabel, curarray in linked_arrays.items():
|
2747
|
+
if curarray.plotted:
|
2748
|
+
exit=False
|
2581
2749
|
|
2582
|
-
|
2583
|
-
|
2584
|
-
|
2585
|
-
gridto.SetColLabelValue(3,'value')
|
2586
|
-
gridto.SetColLabelValue(4,'s curvi')
|
2587
|
-
gridto.SetColLabelValue(5,'in use')
|
2750
|
+
if exit:
|
2751
|
+
logging.warning(_('No plotted linked arrays'))
|
2752
|
+
return
|
2588
2753
|
|
2589
|
-
nb=gridto.GetNumberRows()
|
2590
|
-
if len(self.myvertices)-nb>0:
|
2591
|
-
gridto.AppendRows(len(self.myvertices)-nb)
|
2592
2754
|
k=0
|
2593
|
-
for curv in self.myvertices:
|
2594
|
-
gridto.SetCellValue(k,0,str(curv.x))
|
2595
|
-
gridto.SetCellValue(k,1,str(curv.y))
|
2596
|
-
gridto.SetCellValue(k,2,str(curv.z))
|
2597
|
-
gridto.SetCellValue(k,5,'1' if curv.in_use else '0')
|
2598
|
-
k+=1
|
2599
2755
|
|
2600
|
-
|
2601
|
-
|
2602
|
-
|
2603
|
-
|
2604
|
-
curv:wolfvertex
|
2756
|
+
myls = self.asshapely_ls()
|
2757
|
+
length = myls.length
|
2758
|
+
tol=length/10.
|
2759
|
+
ax.set_xlim(0-tol,length+tol)
|
2605
2760
|
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2609
|
-
x=gridfrom.GetCellValue(k,0)
|
2610
|
-
y=gridfrom.GetCellValue(k,1)
|
2611
|
-
z=gridfrom.GetCellValue(k,2)
|
2612
|
-
inuse = gridfrom.GetCellValue(k,5)
|
2613
|
-
if z=='':
|
2614
|
-
z=0.
|
2615
|
-
if x!='':
|
2616
|
-
if k<self.nbvertices:
|
2617
|
-
self.myvertices[k].x=float(x)
|
2618
|
-
self.myvertices[k].y=float(y)
|
2619
|
-
self.myvertices[k].z=float(z)
|
2620
|
-
self.myvertices[k].in_use = inuse=='1'
|
2621
|
-
else:
|
2622
|
-
newvert=wolfvertex(float(x),float(y),float(z))
|
2623
|
-
self.add_vertex(newvert)
|
2624
|
-
k+=1
|
2625
|
-
else:
|
2626
|
-
break
|
2761
|
+
zmin=99999.
|
2762
|
+
zmax=-99999.
|
2763
|
+
nullvalue = -99999
|
2627
2764
|
|
2628
|
-
|
2629
|
-
|
2765
|
+
for curlabel, curarray in linked_arrays.items():
|
2766
|
+
if curarray.plotted:
|
2630
2767
|
|
2631
|
-
|
2632
|
-
self.prepare_shapely()
|
2768
|
+
ds = curarray.get_dxdy_min()
|
2633
2769
|
|
2634
|
-
|
2770
|
+
nb = int(np.ceil(length/ds*2))
|
2635
2771
|
|
2636
|
-
|
2637
|
-
"""
|
2638
|
-
calcul et retour des positions curvilignes 2D
|
2639
|
-
"""
|
2640
|
-
s2d=np.zeros(self.nbvertices)
|
2641
|
-
for k in range(1,self.nbvertices):
|
2642
|
-
s2d[k]=s2d[k-1]+self.myvertices[k-1].dist2D(self.myvertices[k])
|
2772
|
+
alls = np.linspace(0,int(length),nb)
|
2643
2773
|
|
2644
|
-
|
2774
|
+
pts = [myls.interpolate(curs) for curs in alls]
|
2645
2775
|
|
2646
|
-
|
2647
|
-
"""
|
2648
|
-
calcul et retour des positions curvilignes 3D
|
2649
|
-
"""
|
2650
|
-
s3d=np.zeros(self.nbvertices)
|
2651
|
-
for k in range(1,self.nbvertices):
|
2652
|
-
s3d[k]=s3d[k-1]+self.myvertices[k-1].dist3D(self.myvertices[k])
|
2776
|
+
allz = np.asarray([curarray.get_value(curpt.x,curpt.y, nullvalue= nullvalue) for curpt in pts])
|
2653
2777
|
|
2654
|
-
|
2778
|
+
zmaxloc=np.max(allz[allz!=nullvalue])
|
2779
|
+
zminloc=np.min(allz[allz!=nullvalue])
|
2655
2780
|
|
2656
|
-
|
2657
|
-
|
2658
|
-
Calcule et retourne la distance horizontale cumulée ou non
|
2659
|
-
de chaque point vis-à-vis du premier point
|
2781
|
+
zmax=max(zmax,zmaxloc)
|
2782
|
+
zmin=min(zmin,zminloc)
|
2660
2783
|
|
2661
|
-
|
2784
|
+
if np.max(allz)>nullvalue:
|
2785
|
+
# select parts
|
2786
|
+
if nullvalue in allz:
|
2787
|
+
# find all parts separated by nullvalue
|
2788
|
+
nulls = np.argwhere(allz==nullvalue)
|
2789
|
+
nulls = np.insert(nulls,0,-1)
|
2790
|
+
nulls = np.append(nulls,len(allz))
|
2662
2791
|
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2792
|
+
addlabel = True
|
2793
|
+
for i in range(len(nulls)-1):
|
2794
|
+
if nulls[i+1]-nulls[i]>1:
|
2795
|
+
ax.plot(alls[nulls[i]+1:nulls[i+1]],allz[nulls[i]+1:nulls[i+1]],
|
2796
|
+
color=colors[np.mod(k,3)],
|
2797
|
+
lw=2.0,
|
2798
|
+
label=curlabel if addlabel else None)
|
2799
|
+
addlabel = False
|
2666
2800
|
|
2667
|
-
|
2668
|
-
|
2801
|
+
else:
|
2802
|
+
ax.plot(alls,allz,
|
2803
|
+
color=colors[np.mod(k,3)],
|
2804
|
+
lw=2.0,
|
2805
|
+
label=curlabel)
|
2806
|
+
k+=1
|
2669
2807
|
|
2670
|
-
|
2671
|
-
|
2672
|
-
|
2808
|
+
ax.set_ylim(zmin,zmax)
|
2809
|
+
ax.legend()
|
2810
|
+
ax.grid()
|
2811
|
+
fig.canvas.draw()
|
2812
|
+
|
2813
|
+
return fig,ax
|
2814
|
+
|
2815
|
+
def plot_linked_wx(self, fig:MplFig, linked_arrays:dict):
|
2816
|
+
"""
|
2817
|
+
Graphique Matplolib de valeurs dans les matrices liées.
|
2818
|
+
|
2819
|
+
Version pour wxPython
|
2820
|
+
"""
|
2821
|
+
|
2822
|
+
colors=['red','blue','green']
|
2823
|
+
|
2824
|
+
exit=True
|
2825
|
+
for curlabel, curarray in linked_arrays.items():
|
2826
|
+
if curarray.plotted:
|
2827
|
+
exit=False
|
2828
|
+
|
2829
|
+
if exit:
|
2830
|
+
return
|
2831
|
+
|
2832
|
+
k=0
|
2833
|
+
|
2834
|
+
myls = self.asshapely_ls()
|
2835
|
+
length = myls.length
|
2836
|
+
tol=length/10.
|
2837
|
+
fig.cur_ax.set_xlim(0-tol,length+tol)
|
2838
|
+
|
2839
|
+
zmin=99999.
|
2840
|
+
zmax=-99999.
|
2841
|
+
nullvalue = -99999
|
2842
|
+
|
2843
|
+
for curlabel, curarray in linked_arrays.items():
|
2844
|
+
if curarray.plotted:
|
2845
|
+
|
2846
|
+
ds = curarray.get_dxdy_min()
|
2847
|
+
|
2848
|
+
nb = int(np.ceil(length/ds*2))
|
2849
|
+
|
2850
|
+
alls = np.linspace(0,int(length),nb)
|
2851
|
+
|
2852
|
+
pts = [myls.interpolate(curs) for curs in alls]
|
2853
|
+
|
2854
|
+
allz = np.asarray([curarray.get_value(curpt.x,curpt.y, nullvalue= nullvalue) for curpt in pts])
|
2855
|
+
|
2856
|
+
zmaxloc=np.max(allz[allz!=nullvalue])
|
2857
|
+
zminloc=np.min(allz[allz!=nullvalue])
|
2858
|
+
|
2859
|
+
zmax=max(zmax,zmaxloc)
|
2860
|
+
zmin=min(zmin,zminloc)
|
2861
|
+
|
2862
|
+
if np.max(allz)>nullvalue:
|
2863
|
+
# select parts
|
2864
|
+
if nullvalue in allz:
|
2865
|
+
# find all parts separated by nullvalue
|
2866
|
+
nulls = np.argwhere(allz==nullvalue)
|
2867
|
+
nulls = np.insert(nulls,0,-1)
|
2868
|
+
nulls = np.append(nulls,len(allz))
|
2869
|
+
|
2870
|
+
addlabel = True
|
2871
|
+
for i in range(len(nulls)-1):
|
2872
|
+
if nulls[i+1]-nulls[i]>1:
|
2873
|
+
fig.plot(alls[nulls[i]+1:nulls[i+1]],allz[nulls[i]+1:nulls[i+1]],
|
2874
|
+
color=colors[np.mod(k,3)],
|
2875
|
+
lw=2.0,
|
2876
|
+
label=curlabel if addlabel else None)
|
2877
|
+
addlabel = False
|
2878
|
+
|
2879
|
+
else:
|
2880
|
+
fig.plot(alls,allz,
|
2881
|
+
color=colors[np.mod(k,3)],
|
2882
|
+
lw=2.0,
|
2883
|
+
label=curlabel)
|
2884
|
+
k+=1
|
2885
|
+
|
2886
|
+
fig.cur_ax.set_ylim(zmin,zmax)
|
2887
|
+
fig.cur_ax.legend()
|
2888
|
+
fig.cur_ax.grid()
|
2889
|
+
|
2890
|
+
return fig
|
2891
|
+
|
2892
|
+
def plot_mpl(self, show=False,
|
2893
|
+
forceaspect=True,
|
2894
|
+
fig:Figure=None,
|
2895
|
+
ax:Axes=None,
|
2896
|
+
labels:dict={},
|
2897
|
+
clear_ax:bool =True):
|
2898
|
+
"""
|
2899
|
+
Graphique Matplolib du vecteur - SZ coordinates ONLY
|
2900
|
+
|
2901
|
+
DEPRECATED: Use plot_matplotlib_sz instead.
|
2902
|
+
"""
|
2903
|
+
warnings.warn("plot_mpl is deprecated, use plot_matplotlib_sz instead", DeprecationWarning, stacklevel=2)
|
2904
|
+
|
2905
|
+
x,y=self.get_sz()
|
2906
|
+
|
2907
|
+
xmin=x[0]
|
2908
|
+
xmax=x[-1]
|
2909
|
+
ymin=np.min(y)
|
2910
|
+
ymax=np.max(y)
|
2911
|
+
|
2912
|
+
if ax is None:
|
2913
|
+
redraw=False
|
2914
|
+
fig = plt.figure()
|
2915
|
+
ax=fig.add_subplot(111)
|
2916
|
+
else:
|
2917
|
+
redraw=True
|
2918
|
+
if clear_ax:
|
2919
|
+
# Clear the axes if specified
|
2920
|
+
ax.cla()
|
2921
|
+
|
2922
|
+
if 'title' in labels.keys():
|
2923
|
+
ax.set_title(labels['title'])
|
2924
|
+
if 'xlabel' in labels.keys():
|
2925
|
+
ax.set_xlabel(labels['xlabel'])
|
2926
|
+
if 'ylabel' in labels.keys():
|
2927
|
+
ax.set_ylabel(labels['ylabel'])
|
2928
|
+
|
2929
|
+
if ymax>-99999.:
|
2930
|
+
|
2931
|
+
dy=ymax-ymin
|
2932
|
+
ymin-=dy/4.
|
2933
|
+
ymax+=dy/4.
|
2934
|
+
|
2935
|
+
ax.plot(x,y,color='black',
|
2936
|
+
lw=2.0,
|
2937
|
+
label=self.myname)
|
2938
|
+
|
2939
|
+
ax.legend()
|
2940
|
+
|
2941
|
+
tol=(xmax-xmin)/10.
|
2942
|
+
ax.set_xlim(xmin-tol,xmax+tol)
|
2943
|
+
ax.set_ylim(ymin,ymax)
|
2944
|
+
|
2945
|
+
if forceaspect:
|
2946
|
+
aspect=1.0*(ymax-ymin)/(xmax-xmin)*(ax.get_xlim()[1] - ax.get_xlim()[0]) / (ax.get_ylim()[1] - ax.get_ylim()[0])
|
2947
|
+
ax.set_aspect(aspect)
|
2948
|
+
|
2949
|
+
if show:
|
2950
|
+
fig.show()
|
2951
|
+
|
2952
|
+
if redraw:
|
2953
|
+
fig.canvas.draw()
|
2954
|
+
|
2955
|
+
return fig,ax
|
2956
|
+
|
2957
|
+
def _get_textfont(self):
|
2958
|
+
""" Retunr a 'Text_Infos' instance for the legend """
|
2959
|
+
|
2960
|
+
r,g,b = getRGBfromI(self.myprop.legendcolor)
|
2961
|
+
tinfos = Text_Infos(self.myprop.legendpriority,
|
2962
|
+
(np.cos(self.myprop.legendorientation/180*np.pi),
|
2963
|
+
np.sin(self.myprop.legendorientation/180*np.pi)),
|
2964
|
+
self.myprop.legendfontname,
|
2965
|
+
self.myprop.legendfontsize,
|
2966
|
+
colour=(r,g,b,255),
|
2967
|
+
dimsreal=(self.myprop.legendlength,
|
2968
|
+
self.myprop.legendheight),
|
2969
|
+
relative_position=self.myprop.legendrelpos)
|
2970
|
+
|
2971
|
+
return tinfos
|
2972
|
+
|
2973
|
+
def _get_textfont_idx(self):
|
2974
|
+
""" Retunr a 'Text_Infos' instance for the legend """
|
2975
|
+
|
2976
|
+
r,g,b = getRGBfromI(self.myprop.color)
|
2977
|
+
tinfos = Text_Infos(3,
|
2978
|
+
(1., 0.),
|
2979
|
+
self.myprop.legendfontname,
|
2980
|
+
12,
|
2981
|
+
colour=(r,g,b,255),
|
2982
|
+
dimsreal=(self.myprop.legendlength,
|
2983
|
+
self.myprop.legendheight),
|
2984
|
+
relative_position=7)
|
2985
|
+
|
2986
|
+
return tinfos
|
2987
|
+
|
2988
|
+
def add2tree(self, tree:TreeListCtrl, root):
|
2989
|
+
"""
|
2990
|
+
Ajout de l'objte à un TreeListCtrl wx
|
2991
|
+
"""
|
2992
|
+
self.mytree=tree
|
2993
|
+
self.myitem=tree.AppendItem(root, self.myname,data=self)
|
2994
|
+
if self.myprop.used:
|
2995
|
+
tree.CheckItem(self.myitem)
|
2996
|
+
|
2997
|
+
def unuse(self):
|
2998
|
+
"""
|
2999
|
+
L'objet n'est plus à utiliser
|
3000
|
+
"""
|
3001
|
+
self.myprop.used=False
|
3002
|
+
if self.mytree is not None:
|
3003
|
+
self.mytree.UncheckItem(self.myitem)
|
3004
|
+
|
3005
|
+
self._reset_listogl()
|
3006
|
+
|
3007
|
+
def use(self):
|
3008
|
+
"""
|
3009
|
+
L'objet n'est plus à utiliser
|
3010
|
+
"""
|
3011
|
+
self.myprop.used=True
|
3012
|
+
if self.mytree is not None:
|
3013
|
+
self.mytree.CheckItem(self.myitem)
|
3014
|
+
|
3015
|
+
|
3016
|
+
self._reset_listogl()
|
3017
|
+
|
3018
|
+
def fillgrid(self, gridto:CpGrid):
|
3019
|
+
"""
|
3020
|
+
Remplissage d'un CpGrid
|
3021
|
+
"""
|
3022
|
+
curv:wolfvertex
|
3023
|
+
|
3024
|
+
gridto.SetColLabelValue(0,'X')
|
3025
|
+
gridto.SetColLabelValue(1,'Y')
|
3026
|
+
gridto.SetColLabelValue(2,'Z')
|
3027
|
+
gridto.SetColLabelValue(3,'value')
|
3028
|
+
gridto.SetColLabelValue(4,'s curvi')
|
3029
|
+
gridto.SetColLabelValue(5,'in use')
|
3030
|
+
|
3031
|
+
nb=gridto.GetNumberRows()
|
3032
|
+
if len(self.myvertices)-nb>0:
|
3033
|
+
gridto.AppendRows(len(self.myvertices)-nb)
|
3034
|
+
k=0
|
3035
|
+
for curv in self.myvertices:
|
3036
|
+
gridto.SetCellValue(k,0,str(curv.x))
|
3037
|
+
gridto.SetCellValue(k,1,str(curv.y))
|
3038
|
+
gridto.SetCellValue(k,2,str(curv.z))
|
3039
|
+
gridto.SetCellValue(k,5,'1' if curv.in_use else '0')
|
3040
|
+
k+=1
|
3041
|
+
|
3042
|
+
def _fillgrid_only_i(self, gridto:CpGrid):
|
3043
|
+
"""
|
3044
|
+
Remplissage d'un CpGrid
|
3045
|
+
"""
|
3046
|
+
curv:wolfvertex
|
3047
|
+
|
3048
|
+
gridto.SetColLabelValue(0,'X')
|
3049
|
+
gridto.SetColLabelValue(1,'Y')
|
3050
|
+
gridto.SetColLabelValue(2,'Z')
|
3051
|
+
gridto.SetColLabelValue(3,'value')
|
3052
|
+
gridto.SetColLabelValue(4,'s curvi')
|
3053
|
+
gridto.SetColLabelValue(5,'in use')
|
3054
|
+
|
3055
|
+
nb=gridto.GetNumberRows()
|
3056
|
+
if len(self.myvertices)-nb>0:
|
3057
|
+
gridto.AppendRows(len(self.myvertices)-nb)
|
3058
|
+
k=0
|
3059
|
+
|
3060
|
+
for curv in self.myvertices:
|
3061
|
+
gridto.SetCellValue(k, 5, '1' if curv.in_use else '0')
|
3062
|
+
k+=1
|
3063
|
+
|
3064
|
+
def updatefromgrid(self,gridfrom:CpGrid):
|
3065
|
+
"""
|
3066
|
+
Mise à jour depuis un CpGrid
|
3067
|
+
"""
|
3068
|
+
curv:wolfvertex
|
3069
|
+
|
3070
|
+
nbl=gridfrom.GetNumberRows()
|
3071
|
+
k=0
|
3072
|
+
while k<nbl:
|
3073
|
+
x=gridfrom.GetCellValue(k,0)
|
3074
|
+
y=gridfrom.GetCellValue(k,1)
|
3075
|
+
z=gridfrom.GetCellValue(k,2)
|
3076
|
+
inuse = gridfrom.GetCellValue(k,5)
|
3077
|
+
if z=='':
|
3078
|
+
z=0.
|
3079
|
+
if x!='':
|
3080
|
+
if k<self.nbvertices:
|
3081
|
+
self.myvertices[k].x=float(x)
|
3082
|
+
self.myvertices[k].y=float(y)
|
3083
|
+
self.myvertices[k].z=float(z)
|
3084
|
+
self.myvertices[k].in_use = inuse=='1'
|
3085
|
+
else:
|
3086
|
+
newvert=wolfvertex(float(x),float(y),float(z))
|
3087
|
+
self.add_vertex(newvert)
|
3088
|
+
k+=1
|
3089
|
+
else:
|
3090
|
+
break
|
3091
|
+
|
3092
|
+
while k<self.nbvertices:
|
3093
|
+
self.myvertices.pop(k)
|
3094
|
+
|
3095
|
+
if self._linestring is not None or self._polygon is not None:
|
3096
|
+
self.prepare_shapely()
|
3097
|
+
|
3098
|
+
self._reset_listogl()
|
3099
|
+
|
3100
|
+
def get_s2d(self) -> np.ndarray:
|
3101
|
+
"""
|
3102
|
+
calcul et retour des positions curvilignes 2D
|
3103
|
+
"""
|
3104
|
+
s2d=np.zeros(self.nbvertices)
|
3105
|
+
for k in range(1,self.nbvertices):
|
3106
|
+
s2d[k]=s2d[k-1]+self.myvertices[k-1].dist2D(self.myvertices[k])
|
3107
|
+
|
3108
|
+
return s2d
|
3109
|
+
|
3110
|
+
def get_s3d(self) -> np.ndarray:
|
3111
|
+
"""
|
3112
|
+
calcul et retour des positions curvilignes 3D
|
3113
|
+
"""
|
3114
|
+
s3d=np.zeros(self.nbvertices)
|
3115
|
+
for k in range(1,self.nbvertices):
|
3116
|
+
s3d[k]=s3d[k-1]+self.myvertices[k-1].dist3D(self.myvertices[k])
|
3117
|
+
|
3118
|
+
return s3d
|
3119
|
+
|
3120
|
+
def get_sz(self, cumul=True):
|
3121
|
+
"""
|
3122
|
+
Calcule et retourne la distance horizontale cumulée ou non
|
3123
|
+
de chaque point vis-à-vis du premier point
|
3124
|
+
|
3125
|
+
Utile pour le tracé de sections en travers ou des vérifications de position
|
3126
|
+
|
3127
|
+
:param cumul: si True, retourne la distance cumulée 2D. si False, retourne la distance 2D entre chaque point et le premier.
|
3128
|
+
"""
|
3129
|
+
z = np.asarray([self.myvertices[i].z for i in range(self.nbvertices)])
|
3130
|
+
|
3131
|
+
nb = len(z)
|
3132
|
+
s = np.zeros(nb)
|
3133
|
+
|
3134
|
+
if cumul:
|
3135
|
+
x1 = self.myvertices[0].x
|
3136
|
+
y1 = self.myvertices[0].y
|
2673
3137
|
for i in range(nb-1):
|
2674
3138
|
x2 = self.myvertices[i+1].x
|
2675
3139
|
y2 = self.myvertices[i+1].y
|
@@ -2878,346 +3342,135 @@ class vector:
|
|
2878
3342
|
else:
|
2879
3343
|
for k in range(k1+1,k2+1,-1):
|
2880
3344
|
if self.myvertices[k].dist2D(newvec.myvertices[-1])!=0.:
|
2881
|
-
newvec.add_vertex(self.myvertices[k])
|
2882
|
-
|
2883
|
-
if [v2.x,v2.y,v2.z] != [newvec.myvertices[-1].x,newvec.myvertices[-1].y,newvec.myvertices[-1].z]:
|
2884
|
-
newvec.add_vertex(v2)
|
2885
|
-
|
2886
|
-
# if newvec.nbvertices==0:
|
2887
|
-
# a=1
|
2888
|
-
# if newvec.nbvertices==1:
|
2889
|
-
# a=1
|
2890
|
-
# newvec.update_lengths()
|
2891
|
-
# if np.min(newvec._lengthparts2D)==0.:
|
2892
|
-
# a=1
|
2893
|
-
return newvec
|
2894
|
-
|
2895
|
-
def get_values_linked_polygon(self, linked_arrays:list, getxy=False) -> dict:
|
2896
|
-
"""
|
2897
|
-
Retourne les valeurs contenue dans le polygone
|
2898
|
-
|
2899
|
-
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
2900
|
-
"""
|
2901
|
-
vals={}
|
2902
|
-
|
2903
|
-
for curarray in linked_arrays:
|
2904
|
-
if curarray.plotted:
|
2905
|
-
vals[curarray.idx] = curarray.get_values_insidepoly(self, getxy=getxy)
|
2906
|
-
else:
|
2907
|
-
vals[curarray.idx] = None
|
2908
|
-
|
2909
|
-
return vals
|
2910
|
-
|
2911
|
-
def get_all_values_linked_polygon(self, linked_arrays, getxy=False) -> dict:
|
2912
|
-
"""
|
2913
|
-
Retourne toutes les valeurs contenue dans le polygone --> utile au moins pour les résultats WOLF2D
|
2914
|
-
|
2915
|
-
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
2916
|
-
"""
|
2917
|
-
vals={}
|
2918
|
-
|
2919
|
-
for curarray in linked_arrays:
|
2920
|
-
if curarray.plotted:
|
2921
|
-
vals[curarray.idx] = curarray.get_all_values_insidepoly(self, getxy=getxy)
|
2922
|
-
else:
|
2923
|
-
vals[curarray.idx] = None
|
2924
|
-
|
2925
|
-
return vals
|
2926
|
-
|
2927
|
-
def get_all_values_linked_polyline(self,linked_arrays, getxy=True) -> dict:
|
2928
|
-
"""
|
2929
|
-
Retourne toutes les valeurs sous la polyligne --> utile au moins pour les résultats WOLF2D
|
2930
|
-
|
2931
|
-
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
2932
|
-
"""
|
2933
|
-
vals={}
|
2934
|
-
|
2935
|
-
for curarray in linked_arrays:
|
2936
|
-
if curarray.plotted:
|
2937
|
-
vals[curarray.idx], xy = curarray.get_all_values_underpoly(self, getxy=getxy)
|
2938
|
-
else:
|
2939
|
-
vals[curarray.idx] = None
|
2940
|
-
|
2941
|
-
return vals
|
2942
|
-
|
2943
|
-
def get_values_on_vertices(self,curarray):
|
2944
|
-
"""
|
2945
|
-
Récupération des valeurs sous les vertices et stockage dans la coordonnée 'z'
|
2946
|
-
"""
|
2947
|
-
if not curarray.plotted:
|
2948
|
-
return
|
2949
|
-
|
2950
|
-
for curpt in self.myvertices:
|
2951
|
-
curpt.z = curarray.get_value(curpt.x,curpt.y)
|
2952
|
-
|
2953
|
-
def get_values_linked(self, linked_arrays:dict, refine=True, filter_null = False):
|
2954
|
-
"""
|
2955
|
-
Récupération des valeurs dans les matrices liées sous les vertices et stockage dans la coordonnée 'z'
|
2956
|
-
Possibilité de raffiner la discrétisation pour obtenir au moins une valeur par maille
|
2957
|
-
"""
|
2958
|
-
|
2959
|
-
exit=True
|
2960
|
-
for curlabel, curarray in linked_arrays.items():
|
2961
|
-
if curarray.plotted:
|
2962
|
-
# at least one plotted array
|
2963
|
-
exit=False
|
2964
|
-
|
2965
|
-
if exit:
|
2966
|
-
return
|
2967
|
-
|
2968
|
-
if refine:
|
2969
|
-
myzone=zone(name='linked_arrays - fine step')
|
2970
|
-
|
2971
|
-
for curlabel, curarray in linked_arrays.items():
|
2972
|
-
if curarray.plotted:
|
2973
|
-
|
2974
|
-
myvec=vector(name=curlabel,parentzone=myzone)
|
2975
|
-
myzone.add_vector(myvec)
|
2976
|
-
|
2977
|
-
ds = curarray.get_dxdy_min()
|
2978
|
-
|
2979
|
-
pts = self._refine2D(ds)
|
2980
|
-
|
2981
|
-
allz = [curarray.get_value(curpt.x, curpt.y, nullvalue=-99999) for curpt in pts]
|
2982
|
-
|
2983
|
-
if filter_null:
|
2984
|
-
for curpt,curz in zip(pts,allz):
|
2985
|
-
if curz!=-99999:
|
2986
|
-
myvec.add_vertex(wolfvertex(curpt.x,curpt.y,curz))
|
2987
|
-
else:
|
2988
|
-
for curpt,curz in zip(pts,allz):
|
2989
|
-
myvec.add_vertex(wolfvertex(curpt.x,curpt.y,curz))
|
2990
|
-
|
2991
|
-
else:
|
2992
|
-
myzone=zone(name='linked_arrays')
|
2993
|
-
for curlabel, curarray in linked_arrays.items():
|
2994
|
-
if curarray.plotted:
|
2995
|
-
|
2996
|
-
myvec=vector(name=curlabel,parentzone=myzone)
|
2997
|
-
myzone.add_vector(myvec)
|
2998
|
-
|
2999
|
-
if filter_null:
|
3000
|
-
for curpt in self.myvertices:
|
3001
|
-
locval = curarray.get_value(curpt.x, curpt.y, nullvalue=-99999)
|
3002
|
-
if locval !=-99999:
|
3003
|
-
myvec.add_vertex(wolfvertex(curpt.x, curpt.y, locval))
|
3004
|
-
else:
|
3005
|
-
for curpt in self.myvertices:
|
3006
|
-
locval = curarray.get_value(curpt.x, curpt.y, nullvalue=-99999)
|
3007
|
-
myvec.add_vertex(wolfvertex(curpt.x, curpt.y, locval))
|
3008
|
-
|
3009
|
-
return myzone
|
3010
|
-
|
3011
|
-
def plot_linked(self, fig, ax, linked_arrays:dict):
|
3012
|
-
"""
|
3013
|
-
Graphique Matplolib de valeurs dans les matrices liées
|
3014
|
-
"""
|
3015
|
-
# from .wolf_array import WolfArray
|
3016
|
-
# from .wolfresults_2D import Wolfresults_2D
|
3017
|
-
|
3018
|
-
colors=['red','blue','green']
|
3019
|
-
|
3020
|
-
exit=True
|
3021
|
-
for curlabel, curarray in linked_arrays.items():
|
3022
|
-
if curarray.plotted:
|
3023
|
-
exit=False
|
3024
|
-
|
3025
|
-
if exit:
|
3026
|
-
logging.warning(_('No plotted linked arrays'))
|
3027
|
-
return
|
3028
|
-
|
3029
|
-
k=0
|
3030
|
-
|
3031
|
-
myls = self.asshapely_ls()
|
3032
|
-
length = myls.length
|
3033
|
-
tol=length/10.
|
3034
|
-
ax.set_xlim(0-tol,length+tol)
|
3035
|
-
|
3036
|
-
zmin=99999.
|
3037
|
-
zmax=-99999.
|
3038
|
-
nullvalue = -99999
|
3039
|
-
|
3040
|
-
for curlabel, curarray in linked_arrays.items():
|
3041
|
-
if curarray.plotted:
|
3042
|
-
|
3043
|
-
ds = curarray.get_dxdy_min()
|
3044
|
-
|
3045
|
-
nb = int(np.ceil(length/ds*2))
|
3046
|
-
|
3047
|
-
alls = np.linspace(0,int(length),nb)
|
3048
|
-
|
3049
|
-
pts = [myls.interpolate(curs) for curs in alls]
|
3050
|
-
|
3051
|
-
allz = np.asarray([curarray.get_value(curpt.x,curpt.y, nullvalue= nullvalue) for curpt in pts])
|
3052
|
-
|
3053
|
-
zmaxloc=np.max(allz[allz!=nullvalue])
|
3054
|
-
zminloc=np.min(allz[allz!=nullvalue])
|
3055
|
-
|
3056
|
-
zmax=max(zmax,zmaxloc)
|
3057
|
-
zmin=min(zmin,zminloc)
|
3058
|
-
|
3059
|
-
if np.max(allz)>nullvalue:
|
3060
|
-
# select parts
|
3061
|
-
if nullvalue in allz:
|
3062
|
-
# find all parts separated by nullvalue
|
3063
|
-
nulls = np.argwhere(allz==nullvalue)
|
3064
|
-
nulls = np.insert(nulls,0,-1)
|
3065
|
-
nulls = np.append(nulls,len(allz))
|
3066
|
-
|
3067
|
-
addlabel = True
|
3068
|
-
for i in range(len(nulls)-1):
|
3069
|
-
if nulls[i+1]-nulls[i]>1:
|
3070
|
-
ax.plot(alls[nulls[i]+1:nulls[i+1]],allz[nulls[i]+1:nulls[i+1]],
|
3071
|
-
color=colors[np.mod(k,3)],
|
3072
|
-
lw=2.0,
|
3073
|
-
label=curlabel if addlabel else None)
|
3074
|
-
addlabel = False
|
3075
|
-
|
3076
|
-
else:
|
3077
|
-
ax.plot(alls,allz,
|
3078
|
-
color=colors[np.mod(k,3)],
|
3079
|
-
lw=2.0,
|
3080
|
-
label=curlabel)
|
3081
|
-
k+=1
|
3345
|
+
newvec.add_vertex(self.myvertices[k])
|
3082
3346
|
|
3083
|
-
|
3084
|
-
|
3085
|
-
ax.grid()
|
3086
|
-
fig.canvas.draw()
|
3347
|
+
if [v2.x,v2.y,v2.z] != [newvec.myvertices[-1].x,newvec.myvertices[-1].y,newvec.myvertices[-1].z]:
|
3348
|
+
newvec.add_vertex(v2)
|
3087
3349
|
|
3088
|
-
|
3350
|
+
# if newvec.nbvertices==0:
|
3351
|
+
# a=1
|
3352
|
+
# if newvec.nbvertices==1:
|
3353
|
+
# a=1
|
3354
|
+
# newvec.update_lengths()
|
3355
|
+
# if np.min(newvec._lengthparts2D)==0.:
|
3356
|
+
# a=1
|
3357
|
+
return newvec
|
3089
3358
|
|
3090
|
-
def
|
3359
|
+
def get_values_linked_polygon(self, linked_arrays:list, getxy=False) -> dict:
|
3091
3360
|
"""
|
3092
|
-
|
3361
|
+
Retourne les valeurs contenue dans le polygone
|
3093
3362
|
|
3094
|
-
|
3363
|
+
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
3095
3364
|
"""
|
3365
|
+
vals={}
|
3096
3366
|
|
3097
|
-
|
3098
|
-
|
3099
|
-
exit=True
|
3100
|
-
for curlabel, curarray in linked_arrays.items():
|
3367
|
+
for curarray in linked_arrays:
|
3101
3368
|
if curarray.plotted:
|
3102
|
-
|
3103
|
-
|
3104
|
-
|
3105
|
-
return
|
3369
|
+
vals[curarray.idx] = curarray.get_values_insidepoly(self, getxy=getxy)
|
3370
|
+
else:
|
3371
|
+
vals[curarray.idx] = None
|
3106
3372
|
|
3107
|
-
|
3373
|
+
return vals
|
3108
3374
|
|
3109
|
-
|
3110
|
-
|
3111
|
-
|
3112
|
-
fig.cur_ax.set_xlim(0-tol,length+tol)
|
3375
|
+
def get_all_values_linked_polygon(self, linked_arrays, getxy=False) -> dict:
|
3376
|
+
"""
|
3377
|
+
Retourne toutes les valeurs contenue dans le polygone --> utile au moins pour les résultats WOLF2D
|
3113
3378
|
|
3114
|
-
|
3115
|
-
|
3116
|
-
|
3379
|
+
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
3380
|
+
"""
|
3381
|
+
vals={}
|
3117
3382
|
|
3118
|
-
for
|
3383
|
+
for curarray in linked_arrays:
|
3119
3384
|
if curarray.plotted:
|
3385
|
+
vals[curarray.idx] = curarray.get_all_values_insidepoly(self, getxy=getxy)
|
3386
|
+
else:
|
3387
|
+
vals[curarray.idx] = None
|
3120
3388
|
|
3121
|
-
|
3122
|
-
|
3123
|
-
nb = int(np.ceil(length/ds*2))
|
3124
|
-
|
3125
|
-
alls = np.linspace(0,int(length),nb)
|
3126
|
-
|
3127
|
-
pts = [myls.interpolate(curs) for curs in alls]
|
3128
|
-
|
3129
|
-
allz = np.asarray([curarray.get_value(curpt.x,curpt.y, nullvalue= nullvalue) for curpt in pts])
|
3130
|
-
|
3131
|
-
zmaxloc=np.max(allz[allz!=nullvalue])
|
3132
|
-
zminloc=np.min(allz[allz!=nullvalue])
|
3389
|
+
return vals
|
3133
3390
|
|
3134
|
-
|
3135
|
-
|
3391
|
+
def get_all_values_linked_polyline(self,linked_arrays, getxy=True) -> dict:
|
3392
|
+
"""
|
3393
|
+
Retourne toutes les valeurs sous la polyligne --> utile au moins pour les résultats WOLF2D
|
3136
3394
|
|
3137
|
-
|
3138
|
-
|
3139
|
-
|
3140
|
-
# find all parts separated by nullvalue
|
3141
|
-
nulls = np.argwhere(allz==nullvalue)
|
3142
|
-
nulls = np.insert(nulls,0,-1)
|
3143
|
-
nulls = np.append(nulls,len(allz))
|
3395
|
+
linked_arrays : liste Python d'objet matriciels WolfArray (ou surcharge)
|
3396
|
+
"""
|
3397
|
+
vals={}
|
3144
3398
|
|
3145
|
-
|
3146
|
-
|
3147
|
-
|
3148
|
-
|
3149
|
-
|
3150
|
-
lw=2.0,
|
3151
|
-
label=curlabel if addlabel else None)
|
3152
|
-
addlabel = False
|
3399
|
+
for curarray in linked_arrays:
|
3400
|
+
if curarray.plotted:
|
3401
|
+
vals[curarray.idx], xy = curarray.get_all_values_underpoly(self, getxy=getxy)
|
3402
|
+
else:
|
3403
|
+
vals[curarray.idx] = None
|
3153
3404
|
|
3154
|
-
|
3155
|
-
fig.plot(alls,allz,
|
3156
|
-
color=colors[np.mod(k,3)],
|
3157
|
-
lw=2.0,
|
3158
|
-
label=curlabel)
|
3159
|
-
k+=1
|
3405
|
+
return vals
|
3160
3406
|
|
3161
|
-
|
3162
|
-
|
3163
|
-
|
3407
|
+
def get_values_on_vertices(self,curarray):
|
3408
|
+
"""
|
3409
|
+
Récupération des valeurs sous les vertices et stockage dans la coordonnée 'z'
|
3410
|
+
"""
|
3411
|
+
if not curarray.plotted:
|
3412
|
+
return
|
3164
3413
|
|
3165
|
-
|
3414
|
+
for curpt in self.myvertices:
|
3415
|
+
curpt.z = curarray.get_value(curpt.x,curpt.y)
|
3166
3416
|
|
3167
|
-
def
|
3417
|
+
def get_values_linked(self, linked_arrays:dict, refine=True, filter_null = False):
|
3168
3418
|
"""
|
3169
|
-
|
3419
|
+
Récupération des valeurs dans les matrices liées sous les vertices et stockage dans la coordonnée 'z'
|
3420
|
+
Possibilité de raffiner la discrétisation pour obtenir au moins une valeur par maille
|
3170
3421
|
"""
|
3171
3422
|
|
3172
|
-
|
3423
|
+
exit=True
|
3424
|
+
for curlabel, curarray in linked_arrays.items():
|
3425
|
+
if curarray.plotted:
|
3426
|
+
# at least one plotted array
|
3427
|
+
exit=False
|
3173
3428
|
|
3174
|
-
|
3175
|
-
|
3176
|
-
ymin=np.min(y)
|
3177
|
-
ymax=np.max(y)
|
3429
|
+
if exit:
|
3430
|
+
return
|
3178
3431
|
|
3179
|
-
if
|
3180
|
-
|
3181
|
-
fig = plt.figure()
|
3182
|
-
ax=fig.add_subplot(111)
|
3183
|
-
else:
|
3184
|
-
redraw=True
|
3185
|
-
ax.cla()
|
3432
|
+
if refine:
|
3433
|
+
myzone=zone(name='linked_arrays - fine step')
|
3186
3434
|
|
3187
|
-
|
3188
|
-
|
3189
|
-
if 'xlabel' in labels.keys():
|
3190
|
-
ax.set_xlabel(labels['xlabel'])
|
3191
|
-
if 'ylabel' in labels.keys():
|
3192
|
-
ax.set_ylabel(labels['ylabel'])
|
3435
|
+
for curlabel, curarray in linked_arrays.items():
|
3436
|
+
if curarray.plotted:
|
3193
3437
|
|
3194
|
-
|
3438
|
+
myvec=vector(name=curlabel,parentzone=myzone)
|
3439
|
+
myzone.add_vector(myvec)
|
3195
3440
|
|
3196
|
-
|
3197
|
-
ymin-=dy/4.
|
3198
|
-
ymax+=dy/4.
|
3441
|
+
ds = curarray.get_dxdy_min()
|
3199
3442
|
|
3200
|
-
|
3201
|
-
lw=2.0,
|
3202
|
-
label=self.myname)
|
3443
|
+
pts = self._refine2D(ds)
|
3203
3444
|
|
3204
|
-
|
3445
|
+
allz = [curarray.get_value(curpt.x, curpt.y, nullvalue=-99999) for curpt in pts]
|
3205
3446
|
|
3206
|
-
|
3207
|
-
|
3208
|
-
|
3447
|
+
if filter_null:
|
3448
|
+
for curpt,curz in zip(pts,allz):
|
3449
|
+
if curz!=-99999:
|
3450
|
+
myvec.add_vertex(wolfvertex(curpt.x,curpt.y,curz))
|
3451
|
+
else:
|
3452
|
+
for curpt,curz in zip(pts,allz):
|
3453
|
+
myvec.add_vertex(wolfvertex(curpt.x,curpt.y,curz))
|
3209
3454
|
|
3210
|
-
|
3211
|
-
|
3212
|
-
|
3455
|
+
else:
|
3456
|
+
myzone=zone(name='linked_arrays')
|
3457
|
+
for curlabel, curarray in linked_arrays.items():
|
3458
|
+
if curarray.plotted:
|
3213
3459
|
|
3214
|
-
|
3215
|
-
|
3460
|
+
myvec=vector(name=curlabel,parentzone=myzone)
|
3461
|
+
myzone.add_vector(myvec)
|
3216
3462
|
|
3217
|
-
|
3218
|
-
|
3463
|
+
if filter_null:
|
3464
|
+
for curpt in self.myvertices:
|
3465
|
+
locval = curarray.get_value(curpt.x, curpt.y, nullvalue=-99999)
|
3466
|
+
if locval !=-99999:
|
3467
|
+
myvec.add_vertex(wolfvertex(curpt.x, curpt.y, locval))
|
3468
|
+
else:
|
3469
|
+
for curpt in self.myvertices:
|
3470
|
+
locval = curarray.get_value(curpt.x, curpt.y, nullvalue=-99999)
|
3471
|
+
myvec.add_vertex(wolfvertex(curpt.x, curpt.y, locval))
|
3219
3472
|
|
3220
|
-
return
|
3473
|
+
return myzone
|
3221
3474
|
|
3222
3475
|
def deepcopy_vector(self, name: str = None, parentzone = None) -> 'vector':
|
3223
3476
|
"""
|
@@ -3279,10 +3532,13 @@ class vector:
|
|
3279
3532
|
|
3280
3533
|
def set_z(self, new_z:np.ndarray):
|
3281
3534
|
""" Set the z values of the vertices """
|
3535
|
+
warnings.warn(_('This method is deprecated, use the z property instead.'), DeprecationWarning, stacklevel=2)
|
3536
|
+
|
3282
3537
|
self.z = new_z
|
3283
3538
|
|
3284
3539
|
@property
|
3285
3540
|
def z(self):
|
3541
|
+
""" Return the z values of the vertices as a numpy array. """
|
3286
3542
|
z = np.asarray([curvert.z for curvert in self.myvertices])
|
3287
3543
|
if self.add_zdatum:
|
3288
3544
|
z+=self.zdatum
|
@@ -3290,30 +3546,37 @@ class vector:
|
|
3290
3546
|
|
3291
3547
|
@property
|
3292
3548
|
def x(self):
|
3549
|
+
""" Return the x values of the vertices as a numpy array. """
|
3293
3550
|
return np.asarray([curvert.x for curvert in self.myvertices])
|
3294
3551
|
|
3295
3552
|
@property
|
3296
3553
|
def y(self):
|
3554
|
+
""" Return the y values of the vertices as a numpy array. """
|
3297
3555
|
return np.asarray([curvert.y for curvert in self.myvertices])
|
3298
3556
|
|
3299
3557
|
@property
|
3300
3558
|
def xy(self):
|
3559
|
+
""" Return the x, y values of the vertices as a 2D numpy array. """
|
3301
3560
|
return np.asarray([[curvert.x, curvert.y] for curvert in self.myvertices])
|
3302
3561
|
|
3303
3562
|
@property
|
3304
3563
|
def xz(self):
|
3564
|
+
""" Return the x, z values of the vertices as a 2D numpy array. """
|
3305
3565
|
return np.asarray([[curvert.x, curvert.z] for curvert in self.myvertices])
|
3306
3566
|
|
3307
3567
|
@property
|
3308
3568
|
def xyz(self):
|
3569
|
+
""" Return the x, y, z values of the vertices as a 3D numpy array. """
|
3309
3570
|
return self.asnparray3d()
|
3310
3571
|
|
3311
3572
|
@property
|
3312
3573
|
def i(self):
|
3574
|
+
""" Return the in_use values of the vertices. """
|
3313
3575
|
return np.asarray([curvert.in_use for curvert in self.myvertices])
|
3314
3576
|
|
3315
3577
|
@property
|
3316
3578
|
def xyzi(self):
|
3579
|
+
""" Return the x, y, z and in_use values of the vertices. """
|
3317
3580
|
x = self.x
|
3318
3581
|
y = self.y
|
3319
3582
|
z = self.z
|
@@ -3322,20 +3585,27 @@ class vector:
|
|
3322
3585
|
|
3323
3586
|
@property
|
3324
3587
|
def xyi(self):
|
3588
|
+
""" Return the x, y and in_use values of the vertices. """
|
3325
3589
|
return np.asarray([[curvert.x, curvert.y, curvert.in_use] for curvert in self.myvertices])
|
3326
3590
|
|
3327
3591
|
@property
|
3328
3592
|
def sz_curvi(self):
|
3593
|
+
""" Return the curvilinear abscissa and thz Z-value of the vector. """
|
3329
3594
|
return self.get_sz()
|
3330
3595
|
|
3331
3596
|
@property
|
3332
3597
|
def s_curvi(self):
|
3598
|
+
""" Return the curvilinear abscissa of the vector. """
|
3333
3599
|
sz = self.get_sz()
|
3334
3600
|
return sz[0]
|
3335
3601
|
|
3336
3602
|
@x.setter
|
3337
3603
|
def x(self, new_x:np.ndarray | list):
|
3338
|
-
""" Set the x values of the vertices
|
3604
|
+
""" Set the x values of the vertices.
|
3605
|
+
|
3606
|
+
:param new_x: numpy array or list with x values - must have the same length as the number of vertices
|
3607
|
+
:type new_x: np.ndarray | list
|
3608
|
+
"""
|
3339
3609
|
|
3340
3610
|
if isinstance(new_x, list):
|
3341
3611
|
new_x = np.array(new_x)
|
@@ -3352,7 +3622,11 @@ class vector:
|
|
3352
3622
|
|
3353
3623
|
@y.setter
|
3354
3624
|
def y(self, new_y:np.ndarray | list):
|
3355
|
-
""" Set the y values of the vertices
|
3625
|
+
""" Set the y values of the vertices.
|
3626
|
+
|
3627
|
+
:param new_y: numpy array or list with y values - must have the same length as the number of vertices
|
3628
|
+
:type new_y: np.ndarray | list
|
3629
|
+
"""
|
3356
3630
|
|
3357
3631
|
if isinstance(new_y, list):
|
3358
3632
|
new_y = np.array(new_y)
|
@@ -3371,7 +3645,8 @@ class vector:
|
|
3371
3645
|
def z(self, new_z:np.ndarray | float | list):
|
3372
3646
|
""" Set the z values of the vertices
|
3373
3647
|
|
3374
|
-
|
3648
|
+
:param new_z: numpy array, float or list (but WolfArray is supported too)
|
3649
|
+
:type new_z: np.ndarray | float | list | WolfArray
|
3375
3650
|
"""
|
3376
3651
|
from .wolf_array import WolfArray
|
3377
3652
|
|
@@ -3405,7 +3680,11 @@ class vector:
|
|
3405
3680
|
|
3406
3681
|
@xyz.setter
|
3407
3682
|
def xyz(self, new_xyz:np.ndarray | list):
|
3408
|
-
""" Set the x, y, z values of the vertices
|
3683
|
+
""" Set the x, y, z values of the vertices.
|
3684
|
+
|
3685
|
+
:param new_xyz: numpy array or list with x, y, z values - must have the same length as the number of vertices
|
3686
|
+
:type new_xyz: np.ndarray | list
|
3687
|
+
"""
|
3409
3688
|
|
3410
3689
|
if isinstance(new_xyz, list):
|
3411
3690
|
new_xyz = np.array(new_xyz)
|
@@ -3431,7 +3710,11 @@ class vector:
|
|
3431
3710
|
|
3432
3711
|
@xy.setter
|
3433
3712
|
def xy(self, new_xy:np.ndarray | list):
|
3434
|
-
""" Set the x, y values of the vertices
|
3713
|
+
""" Set the x, y values of the vertices.
|
3714
|
+
|
3715
|
+
:param new_xy: numpy array or list with x, y values - must have the same length as the number of vertices
|
3716
|
+
:type new_xy: np.ndarray | list
|
3717
|
+
"""
|
3435
3718
|
|
3436
3719
|
if isinstance(new_xy, list):
|
3437
3720
|
new_xy = np.array(new_xy)
|
@@ -3449,7 +3732,11 @@ class vector:
|
|
3449
3732
|
|
3450
3733
|
@xz.setter
|
3451
3734
|
def xz(self, new_xz:np.ndarray | list):
|
3452
|
-
""" Set the x, z values of the vertices
|
3735
|
+
""" Set the x, z values of the vertices.
|
3736
|
+
|
3737
|
+
:param new_xz: numpy array or list with x, z values - must have the same length as the number of vertices
|
3738
|
+
:type new_xz: np.ndarray | list
|
3739
|
+
"""
|
3453
3740
|
|
3454
3741
|
if isinstance(new_xz, list):
|
3455
3742
|
new_xz = np.array(new_xz)
|
@@ -3472,7 +3759,11 @@ class vector:
|
|
3472
3759
|
|
3473
3760
|
@xyzi.setter
|
3474
3761
|
def xyzi(self, new_xyzi:np.ndarray | list):
|
3475
|
-
""" Set the x, y, z, in_use values of the vertices
|
3762
|
+
""" Set the x, y, z, in_use values of the vertices.
|
3763
|
+
|
3764
|
+
:param new_xyzi: numpy array or list with x, y, z, in_use values - must have the same length as the number of vertices
|
3765
|
+
:type new_xyzi: np.ndarray | list
|
3766
|
+
"""
|
3476
3767
|
|
3477
3768
|
if isinstance(new_xyzi, list):
|
3478
3769
|
new_xyzi = np.array(new_xyzi)
|
@@ -3492,7 +3783,11 @@ class vector:
|
|
3492
3783
|
|
3493
3784
|
@xyi.setter
|
3494
3785
|
def xyi(self, new_xyi:np.ndarray | list):
|
3495
|
-
""" Set the x, y, in_use values of the vertices
|
3786
|
+
""" Set the x, y, in_use values of the vertices.
|
3787
|
+
|
3788
|
+
:param new_xyi: numpy array or list with x, y, in_use values - must have the same length as the number of vertices
|
3789
|
+
:type new_xyi: np.ndarray | list
|
3790
|
+
"""
|
3496
3791
|
|
3497
3792
|
if isinstance(new_xyi, list):
|
3498
3793
|
new_xyi = np.array(new_xyi)
|
@@ -3511,7 +3806,11 @@ class vector:
|
|
3511
3806
|
|
3512
3807
|
@i.setter
|
3513
3808
|
def i(self, new_i:np.ndarray | list):
|
3514
|
-
""" Set the in_use values of the vertices
|
3809
|
+
""" Set the in_use values of the vertices.
|
3810
|
+
|
3811
|
+
:param new_i: numpy array or list with in_use values - must have the same length as the number of vertices
|
3812
|
+
:type new_i: np.ndarray | list
|
3813
|
+
"""
|
3515
3814
|
|
3516
3815
|
if isinstance(new_i, list):
|
3517
3816
|
new_i = np.array(new_i)
|
@@ -3528,7 +3827,11 @@ class vector:
|
|
3528
3827
|
|
3529
3828
|
@sz_curvi.setter
|
3530
3829
|
def sz_curvi(self, sz_new:np.ndarray | list):
|
3531
|
-
""" Interpolate the
|
3830
|
+
""" Interpolate the vertice Z-coordinates based on a polyline defined as curvilinear abscissa and Z-value.
|
3831
|
+
|
3832
|
+
:param sz_new: numpy array or list with curvilinear abscissa and Z-value pairs
|
3833
|
+
:type sz_new: np.ndarray | list
|
3834
|
+
"""
|
3532
3835
|
|
3533
3836
|
if isinstance(sz_new, list):
|
3534
3837
|
sz_new = np.array(sz_new)
|
@@ -3542,6 +3845,30 @@ class vector:
|
|
3542
3845
|
self._reset_listogl()
|
3543
3846
|
self.reset_linestring()
|
3544
3847
|
|
3848
|
+
@s_curvi.setter
|
3849
|
+
def s_curvi(self, new_s:np.ndarray | list):
|
3850
|
+
""" Replace the vertice XY-coordinates based on the curvilinear abscissa.
|
3851
|
+
|
3852
|
+
:param new_s: numpy array or list with curvilinear abscissa values - must have the same length as the number of vertices
|
3853
|
+
:type new_s: np.ndarray | list
|
3854
|
+
"""
|
3855
|
+
|
3856
|
+
if isinstance(new_s, list):
|
3857
|
+
new_s = np.array(new_s)
|
3858
|
+
|
3859
|
+
if len(new_s) != self.nbvertices:
|
3860
|
+
logging.warning(_('New s values have not the same length as the number of vertices'))
|
3861
|
+
return
|
3862
|
+
|
3863
|
+
poly = self.linestring
|
3864
|
+
|
3865
|
+
for idx, curvert in enumerate(self.myvertices):
|
3866
|
+
curvert.x, curvert.y = poly.interpolate(new_s[idx]).xy
|
3867
|
+
|
3868
|
+
self._reset_listogl()
|
3869
|
+
self.reset_linestring()
|
3870
|
+
|
3871
|
+
|
3545
3872
|
def __str__(self):
|
3546
3873
|
return self.myname
|
3547
3874
|
|
@@ -3804,6 +4131,11 @@ class zone:
|
|
3804
4131
|
# Object can be created from a shapely object
|
3805
4132
|
self.import_shapelyobj(fromshapely)
|
3806
4133
|
|
4134
|
+
def check_if_interior_exists(self):
|
4135
|
+
""" Check if the zone has at least one vector with interior points """
|
4136
|
+
for curvec in self.myvectors:
|
4137
|
+
curvec.check_if_interior_exists()
|
4138
|
+
|
3807
4139
|
def add_values(self, key:str, values:np.ndarray):
|
3808
4140
|
""" add values to the zone """
|
3809
4141
|
|
@@ -4251,7 +4583,7 @@ class zone:
|
|
4251
4583
|
for curvect in self.myvectors:
|
4252
4584
|
curvect.plot_legend(sx, sy, xmin, ymin, xmax, ymax, size)
|
4253
4585
|
|
4254
|
-
def plot_matplotlib(self, ax:plt.Axes):
|
4586
|
+
def plot_matplotlib(self, ax:plt.Axes | tuple[Figure, Axes] = None, **kwargs):
|
4255
4587
|
"""
|
4256
4588
|
Plot the zone using matplotlib
|
4257
4589
|
|
@@ -4259,9 +4591,18 @@ class zone:
|
|
4259
4591
|
:param kwargs: additional arguments
|
4260
4592
|
"""
|
4261
4593
|
|
4594
|
+
if isinstance(ax, tuple):
|
4595
|
+
fig, ax = ax
|
4596
|
+
elif ax is None:
|
4597
|
+
fig, ax = plt.subplots()
|
4598
|
+
else:
|
4599
|
+
fig = ax.figure
|
4600
|
+
|
4262
4601
|
for curvect in self.myvectors:
|
4263
4602
|
curvect.plot_matplotlib(ax)
|
4264
4603
|
|
4604
|
+
return fig, ax
|
4605
|
+
|
4265
4606
|
def select_vectors_from_point(self,x:float,y:float,inside=True):
|
4266
4607
|
"""
|
4267
4608
|
Sélection du vecteur de la zone sur base d'une coordonnée (x,y) -- en 2D
|
@@ -6160,6 +6501,11 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6160
6501
|
|
6161
6502
|
return [curzone.myname for curzone in self.myzones]
|
6162
6503
|
|
6504
|
+
def check_if_interior_exists(self):
|
6505
|
+
""" Check if the zone has at least one vector with interior points """
|
6506
|
+
for curzone in self.myzones:
|
6507
|
+
curzone.check_if_interior_exists()
|
6508
|
+
|
6163
6509
|
def add_values(self, key:str, values:np.ndarray | dict):
|
6164
6510
|
"""
|
6165
6511
|
Add values to the zones
|
@@ -6660,7 +7006,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6660
7006
|
curvect.myprop.color = curcolor
|
6661
7007
|
curvect.myprop.alpha = 180
|
6662
7008
|
curvect.myprop.transparent = True
|
6663
|
-
curvect.myprop.filled = filled
|
7009
|
+
curvect.myprop.filled = filled and curvect.closed
|
6664
7010
|
|
6665
7011
|
def set_width(self, width:int) -> None:
|
6666
7012
|
""" Change with of all vectors in all zones """
|
@@ -6708,23 +7054,36 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6708
7054
|
|
6709
7055
|
def import_dxf(self, fn, imported_elts=['POLYLINE','LWPOLYLINE','LINE']):
|
6710
7056
|
"""
|
6711
|
-
Import
|
7057
|
+
Import of a DXF file as a 'Zones'.
|
7058
|
+
|
7059
|
+
The DXF file is read and the elements are stored in zones based on their layers.
|
7060
|
+
|
7061
|
+
The supported elements are POLYLINE, LWPOLYLINE and LINE.
|
7062
|
+
If you want to import other elements, you must upgrade this routine `import_dxf`.
|
7063
|
+
|
7064
|
+
:param fn: name of the DXF file to import
|
7065
|
+
:param imported_elts: list of DXF elements to import. Default is ['POLYLINE','LWPOLYLINE','LINE'].
|
7066
|
+
:return: None
|
6712
7067
|
"""
|
6713
7068
|
import ezdxf
|
6714
7069
|
|
6715
7070
|
if not path.exists(fn):
|
6716
|
-
|
6717
|
-
logging.warning(_('File not found !') + ' ' + fn)
|
6718
|
-
except:
|
6719
|
-
pass
|
7071
|
+
logging.warning(_('File not found !') + ' ' + fn)
|
6720
7072
|
return
|
6721
7073
|
|
7074
|
+
for elt in imported_elts:
|
7075
|
+
assert elt in ['POLYLINE', 'LWPOLYLINE', 'LINE'], _('Unsupported DXF element: {}').format(elt)
|
7076
|
+
|
7077
|
+
self.is2D = False # we assume it's a 3D DXF
|
7078
|
+
|
6722
7079
|
# Lecture du fichier dxf et identification du modelspace
|
6723
7080
|
doc = ezdxf.readfile(fn)
|
6724
7081
|
msp = doc.modelspace()
|
6725
|
-
layers = doc.layers
|
7082
|
+
# layers = doc.layers
|
6726
7083
|
|
6727
7084
|
used_layers = {}
|
7085
|
+
notloaded = {}
|
7086
|
+
|
6728
7087
|
# Bouclage sur les éléments du DXF pour identifier les layers utiles et ensuite créer les zones adhoc
|
6729
7088
|
for e in msp:
|
6730
7089
|
if doc.layers.get(e.dxf.layer).is_on():
|
@@ -6750,14 +7109,23 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6750
7109
|
curlayer = used_layers[e.dxf.layer]
|
6751
7110
|
curlayer[e.dxftype().lower()]=0
|
6752
7111
|
else:
|
6753
|
-
|
7112
|
+
if not e.dxftype() in notloaded.keys():
|
7113
|
+
notloaded[e.dxftype()] = 0
|
7114
|
+
|
7115
|
+
notloaded[e.dxftype()] += 1
|
7116
|
+
logging.debug(_('DXF element not supported : ') + e.dxftype())
|
6754
7117
|
else:
|
6755
7118
|
logging.info(_('Layer {} is off'.format(e.dxf.layer)))
|
6756
7119
|
|
7120
|
+
if len(notloaded)>0:
|
7121
|
+
logging.warning(_('Not loaded DXF elements : '))
|
7122
|
+
for curtype in notloaded.keys():
|
7123
|
+
logging.warning(_(' {} : {}'.format(curtype, notloaded[curtype])))
|
7124
|
+
|
6757
7125
|
# Création des zones
|
6758
7126
|
for curlayer in used_layers.keys():
|
6759
7127
|
for curtype in used_layers[curlayer].keys():
|
6760
|
-
curzone = used_layers[curlayer][curtype] = zone(name = '{} - {}'.format(curlayer,curtype),is2D=self.is2D,parent=self)
|
7128
|
+
curzone = used_layers[curlayer][curtype] = zone(name = '{} - {}'.format(curlayer,curtype), is2D=self.is2D, parent=self)
|
6761
7129
|
self.add_zone(curzone)
|
6762
7130
|
|
6763
7131
|
# Nouveau bouclage sur les éléments du DXF pour remplissage
|
@@ -6974,12 +7342,21 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
6974
7342
|
for curzone in self.myzones:
|
6975
7343
|
curzone.plot(sx=sx, sy=sy, xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax, size=size)
|
6976
7344
|
|
6977
|
-
def plot_matplotlib(self, ax:
|
7345
|
+
def plot_matplotlib(self, ax:Axes | tuple[Figure, Axes] = None):
|
6978
7346
|
""" Plot with matplotlib """
|
6979
7347
|
|
7348
|
+
if isinstance(ax, tuple):
|
7349
|
+
fig, ax = ax
|
7350
|
+
elif ax is None:
|
7351
|
+
fig, ax = plt.subplots()
|
7352
|
+
else:
|
7353
|
+
fig = ax.figure
|
7354
|
+
|
6980
7355
|
for curzone in self.myzones:
|
6981
7356
|
curzone.plot_matplotlib(ax)
|
6982
7357
|
|
7358
|
+
return fig, ax
|
7359
|
+
|
6983
7360
|
def select_vectors_from_point(self, x:float, y:float, inside=True):
|
6984
7361
|
"""
|
6985
7362
|
Sélection de vecteurs dans chaque zones sur base d'une coordonnée
|
@@ -7070,6 +7447,10 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7070
7447
|
self.updatevertices.SetToolTip(_("Transfer the coordinates from the editor to the memory and update the plot"))
|
7071
7448
|
self.updatevertices.Bind(wx.EVT_BUTTON,self.Onupdatevertices)
|
7072
7449
|
|
7450
|
+
self._test_interior = wx.Button(self,label=_('Test interior'))
|
7451
|
+
self._test_interior.SetToolTip(_("Test if some segments of the active vector are exactly the same"))
|
7452
|
+
self._test_interior.Bind(wx.EVT_BUTTON,self.Ontest_interior)
|
7453
|
+
|
7073
7454
|
self.plot_mpl = wx.Button(self,label=_('Plot xy'))
|
7074
7455
|
self.plot_mpl.SetToolTip(_("Plot the active vector in a new window (matplotlib)"))
|
7075
7456
|
self.plot_mpl.Bind(wx.EVT_BUTTON,self.Onplotmpl)
|
@@ -7079,7 +7460,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7079
7460
|
self.plot_mplsz.Bind(wx.EVT_BUTTON,self.Onplotmplsz)
|
7080
7461
|
|
7081
7462
|
sizer_add_update.Add(self.addrows,1, wx.EXPAND)
|
7082
|
-
sizer_add_update.Add(self.updatevertices,
|
7463
|
+
sizer_add_update.Add(self.updatevertices, 1, wx.EXPAND)
|
7083
7464
|
sizer_add_update.Add(self.plot_mpl,1, wx.EXPAND)
|
7084
7465
|
sizer_add_update.Add(self.plot_mplsz,1, wx.EXPAND)
|
7085
7466
|
|
@@ -7235,6 +7616,8 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7235
7616
|
|
7236
7617
|
box_interp_indices = wx.BoxSizer(wx.HORIZONTAL)
|
7237
7618
|
box_interp_indices.Add(self.interpxyz,1,wx.EXPAND)
|
7619
|
+
box_interp_indices.Add(self._test_interior, 1, wx.EXPAND)
|
7620
|
+
|
7238
7621
|
|
7239
7622
|
boxright.Add(box_interp_indices,0,wx.EXPAND)
|
7240
7623
|
|
@@ -7410,7 +7793,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7410
7793
|
self.fill_structure()
|
7411
7794
|
|
7412
7795
|
self.treelist.SetSize(200,500)
|
7413
|
-
self.SetSize(
|
7796
|
+
self.SetSize(650,700)
|
7414
7797
|
|
7415
7798
|
self.SetSizer(box)
|
7416
7799
|
|
@@ -8781,6 +9164,18 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
8781
9164
|
self.active_vector.updatefromgrid(self.xls)
|
8782
9165
|
self.find_minmax(True)
|
8783
9166
|
|
9167
|
+
def Ontest_interior(self, event:wx.MouseEvent):
|
9168
|
+
""" Test if the active vector has interior portions """
|
9169
|
+
if self.verify_activevec():
|
9170
|
+
return
|
9171
|
+
|
9172
|
+
self.active_vector.check_if_interior_exists()
|
9173
|
+
|
9174
|
+
self.active_vector._fillgrid_only_i(self.xls)
|
9175
|
+
|
9176
|
+
self.get_mapviewer().Paint()
|
9177
|
+
|
9178
|
+
|
8784
9179
|
def Onplotmpl(self, event:wx.MouseEvent):
|
8785
9180
|
"""
|
8786
9181
|
Plot active vector in matplotlib
|