wolfhece 2.2.8__py3-none-any.whl → 2.2.9__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 +1 -1
- wolfhece/PyVertex.py +105 -19
- wolfhece/PyVertexvectors.py +73 -21
- wolfhece/apps/version.py +1 -1
- wolfhece/hydrology/Internal_variables.py +283 -0
- wolfhece/hydrology/Models_characteristics.py +223 -0
- wolfhece/hydrology/Optimisation.py +324 -14
- wolfhece/hydrology/SubBasin.py +112 -28
- wolfhece/hydrology/cst_exchanges.py +1 -0
- wolfhece/libs/WolfDll.dll +0 -0
- wolfhece/pydike.py +1 -1
- wolfhece/wolf_array.py +28 -6
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.9.dist-info}/METADATA +1 -1
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.9.dist-info}/RECORD +17 -15
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.9.dist-info}/WHEEL +0 -0
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.9.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.2.8.dist-info → wolfhece-2.2.9.dist-info}/top_level.txt +0 -0
wolfhece/PyDraw.py
CHANGED
@@ -4305,7 +4305,7 @@ class WolfMapViewer(wx.Frame):
|
|
4305
4305
|
if self.active_cloud is not None and self.active_array is not None:
|
4306
4306
|
|
4307
4307
|
keyvalue='z'
|
4308
|
-
if self.active_cloud.
|
4308
|
+
if self.active_cloud.has_values:
|
4309
4309
|
choices = list(self.active_cloud.myvertices[0].keys())
|
4310
4310
|
dlg = wx.SingleChoiceDialog(None, "Pick the value to interpolate", "Choices", choices)
|
4311
4311
|
ret = dlg.ShowModal()
|
wolfhece/PyVertex.py
CHANGED
@@ -549,7 +549,7 @@ class cloud_vertices(Element_To_Draw):
|
|
549
549
|
|
550
550
|
self.loaded = False
|
551
551
|
|
552
|
-
self.
|
552
|
+
self._header = header
|
553
553
|
|
554
554
|
self.gllist = 0
|
555
555
|
self.forceupdategl = False
|
@@ -570,7 +570,7 @@ class cloud_vertices(Element_To_Draw):
|
|
570
570
|
if Path(fname).suffix.lower() == '.dxf':
|
571
571
|
self.import_from_dxf(self.filename, imported_elts=dxf_imported_elts)
|
572
572
|
elif Path(fname).suffix.lower() == '.shp':
|
573
|
-
self.
|
573
|
+
self.import_from_shapefile(self.filename, bbox=bbox)
|
574
574
|
else:
|
575
575
|
self.readfile(self.filename, header)
|
576
576
|
|
@@ -586,24 +586,53 @@ class cloud_vertices(Element_To_Draw):
|
|
586
586
|
xyz = self.get_xyz()
|
587
587
|
self.mytree = KDTree(xyz)
|
588
588
|
|
589
|
-
def find_nearest(self,
|
589
|
+
def find_nearest(self, xyz:np.ndarray | list, nb:int =1):
|
590
590
|
"""
|
591
|
-
Find nearest neighbors from Scipy KDTree structure based on a copy of the vertices
|
591
|
+
Find nearest neighbors from Scipy KDTree structure based on a copy of the vertices.
|
592
592
|
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
593
|
+
See : https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.KDTree.query.html
|
594
|
+
|
595
|
+
:param xyz: coordinates to find nearest neighbors -- shape (n, m) - where m is the number of coordinates (2 or 3)
|
596
|
+
:param nb: number of nearest neighbors to find
|
597
|
+
:return: list of distances, list of "Wolfvertex", list of elements stored in self.myvertices - or list of lists if xyz is a list of coordinates
|
597
598
|
"""
|
598
599
|
|
599
|
-
|
600
|
-
|
601
|
-
|
600
|
+
if isinstance(xyz, list):
|
601
|
+
if len(xyz) > 0:
|
602
|
+
if isinstance(xyz[0], float | int):
|
603
|
+
logging.warning(_('xyz is a list of floats -- converting to a list of lists'))
|
604
|
+
xyz = [xyz]
|
605
|
+
|
606
|
+
xyz = np.array(xyz)
|
607
|
+
|
608
|
+
try:
|
609
|
+
keys = list(self.myvertices.keys())
|
610
|
+
if self.mytree is None:
|
611
|
+
self.create_kdtree()
|
612
|
+
|
613
|
+
if xyz.shape[1] != self.mytree.m:
|
614
|
+
logging.error(_('Error in find_nearest -- xyz must be a list or 2D array with {} columns').format(self.mytree.m))
|
615
|
+
return None, None, None
|
616
|
+
|
617
|
+
dist, ii = self.mytree.query(xyz, k=nb)
|
602
618
|
|
603
|
-
|
604
|
-
|
619
|
+
if xyz.shape[0] == 1:
|
620
|
+
if nb == 1:
|
621
|
+
return dist[0], self.myvertices[keys[ii[0]]]['vertex'], self.myvertices[keys[ii[0]]]
|
622
|
+
else:
|
623
|
+
return dist[0], [self.myvertices[keys[curi]]['vertex'] for curi in ii[0]], [self.myvertices[keys[curi]] for curi in ii[0]]
|
624
|
+
else:
|
625
|
+
if nb == 1:
|
626
|
+
return dist, [self.myvertices[keys[curi]]['vertex'] for curi in ii], [self.myvertices[keys[curi]] for curi in ii]
|
627
|
+
else:
|
628
|
+
return dist, [[self.myvertices[keys[curi]]['vertex'] for curi in curii] for curii in ii], [[self.myvertices[keys[curi]] for curi in curii] for curii in ii]
|
605
629
|
|
606
|
-
|
630
|
+
except Exception as e:
|
631
|
+
logging.error(_('Error in find_nearest -- {}').format(e))
|
632
|
+
logging.error(_('Check your input data -- it must be a list or 2D array with 3 columns'))
|
633
|
+
return None, None, None
|
634
|
+
|
635
|
+
def init_from_nparray(self, array:np.ndarray):
|
607
636
|
"""
|
608
637
|
Fill-in from nparray -- shape (n,3)
|
609
638
|
"""
|
@@ -624,7 +653,7 @@ class cloud_vertices(Element_To_Draw):
|
|
624
653
|
|
625
654
|
self.plotted = True
|
626
655
|
if not self.loaded:
|
627
|
-
self.readfile(self.filename, self.
|
656
|
+
self.readfile(self.filename, self._header)
|
628
657
|
self.loaded = True
|
629
658
|
|
630
659
|
def uncheck_plot(self, unload=True):
|
@@ -703,11 +732,11 @@ class cloud_vertices(Element_To_Draw):
|
|
703
732
|
nbcols = len(curval)
|
704
733
|
|
705
734
|
if nbcols < 2:
|
706
|
-
|
735
|
+
logging.warning(_('Not enough values on one line -- Retry !!'))
|
707
736
|
return
|
708
737
|
elif nbcols > 3:
|
709
738
|
if headers is None:
|
710
|
-
|
739
|
+
logging.warning(_('No headers -- Retry !!'))
|
711
740
|
return
|
712
741
|
else:
|
713
742
|
if headers[2].lower() == 'z':
|
@@ -847,7 +876,7 @@ class cloud_vertices(Element_To_Draw):
|
|
847
876
|
|
848
877
|
return k
|
849
878
|
|
850
|
-
def
|
879
|
+
def import_from_shapefile(self, fn:str='', targetcolumn:str = 'X1_Y1_Z1', bbox:Polygon = None):
|
851
880
|
"""
|
852
881
|
Importing Shapefile using geopandas library
|
853
882
|
|
@@ -1235,7 +1264,7 @@ class cloud_vertices(Element_To_Draw):
|
|
1235
1264
|
|
1236
1265
|
"""
|
1237
1266
|
|
1238
|
-
if self.
|
1267
|
+
if self._header:
|
1239
1268
|
if key=='vertex':
|
1240
1269
|
xyz = [[curvert['vertex'].x, curvert['vertex'].y, curvert['vertex'].z] for curvert in self.myvertices.values()]
|
1241
1270
|
else:
|
@@ -1244,6 +1273,63 @@ class cloud_vertices(Element_To_Draw):
|
|
1244
1273
|
xyz = [[curvert['vertex'].x, curvert['vertex'].y, curvert['vertex'].z] for curvert in self.myvertices.values()]
|
1245
1274
|
return np.array(xyz)
|
1246
1275
|
|
1276
|
+
@property
|
1277
|
+
def has_values(self) -> bool:
|
1278
|
+
"""
|
1279
|
+
Check if the cloud has values (other than X,Y,Z)
|
1280
|
+
"""
|
1281
|
+
|
1282
|
+
if self._header:
|
1283
|
+
return len(self.myvertices[0]) > 1
|
1284
|
+
else:
|
1285
|
+
return False
|
1286
|
+
|
1287
|
+
@property
|
1288
|
+
def header(self) -> list[str]:
|
1289
|
+
"""
|
1290
|
+
Return the headers of the cloud
|
1291
|
+
"""
|
1292
|
+
|
1293
|
+
if self._header:
|
1294
|
+
return list(self.myvertices[0].keys())
|
1295
|
+
else:
|
1296
|
+
return []
|
1297
|
+
|
1298
|
+
def add_values_by_id_list(self, id:str, values:list[float]):
|
1299
|
+
"""
|
1300
|
+
Add values to the cloud
|
1301
|
+
|
1302
|
+
:param id: use as key for the values
|
1303
|
+
:param values: list of values to be added - must be the same length as number of vertices
|
1304
|
+
|
1305
|
+
"""
|
1306
|
+
|
1307
|
+
if len(values) != len(self.myvertices):
|
1308
|
+
logging.warning(_('Number of values does not match the number of vertices -- Retry !!'))
|
1309
|
+
logging.info(_(('Number of vertices : ')+str(len(self.myvertices))))
|
1310
|
+
return
|
1311
|
+
|
1312
|
+
for item, val in zip(self.myvertices.values(), values):
|
1313
|
+
item[id] = val
|
1314
|
+
|
1315
|
+
self._header = True
|
1316
|
+
|
1317
|
+
@property
|
1318
|
+
def xyz(self) -> np.ndarray:
|
1319
|
+
"""
|
1320
|
+
Alias for get_xyz method
|
1321
|
+
"""
|
1322
|
+
|
1323
|
+
return self.get_xyz(key='vertex')
|
1324
|
+
|
1325
|
+
@property
|
1326
|
+
def nbvertices(self) -> int:
|
1327
|
+
"""
|
1328
|
+
Number of vertices in the cloud
|
1329
|
+
"""
|
1330
|
+
|
1331
|
+
return len(self.myvertices)
|
1332
|
+
|
1247
1333
|
def interp_on_array(self, myarray, key:str='vertex', method:Literal['linear', 'nearest', 'cubic'] = 'linear'):
|
1248
1334
|
"""
|
1249
1335
|
Interpolation of the cloud on a 2D array
|
wolfhece/PyVertexvectors.py
CHANGED
@@ -53,6 +53,9 @@ from .matplotlib_fig import Matplotlib_Figure as MplFig
|
|
53
53
|
from .PyPalette import wolfpalette
|
54
54
|
|
55
55
|
class Triangulation(Element_To_Draw):
|
56
|
+
""" Triangulation based on a listof vertices
|
57
|
+
and triangles enumerated by their vertex indices """
|
58
|
+
|
56
59
|
def __init__(self, fn='', pts=[], tri=[], idx: str = '', plotted: bool = True, mapviewer=None, need_for_wx: bool = False) -> None:
|
57
60
|
super().__init__(idx, plotted, mapviewer, need_for_wx)
|
58
61
|
|
@@ -74,20 +77,24 @@ class Triangulation(Element_To_Draw):
|
|
74
77
|
self.filename=fn
|
75
78
|
self.read(fn)
|
76
79
|
else:
|
77
|
-
self.
|
80
|
+
self.validate_format()
|
78
81
|
pass
|
79
82
|
|
80
|
-
def
|
83
|
+
def validate_format(self):
|
84
|
+
""" Force the format of the data """
|
85
|
+
|
81
86
|
if isinstance(self.pts,list):
|
82
87
|
self.pts = np.asarray(self.pts)
|
83
88
|
if isinstance(self.tri,list):
|
84
89
|
self.tri = np.asarray(self.tri)
|
85
90
|
|
86
91
|
def as_polydata(self) -> pv.PolyData:
|
92
|
+
""" Convert the triangulation to a PyVista PolyData object """
|
87
93
|
|
88
94
|
return pv.PolyData(np.asarray(self.pts),np.column_stack([[3]*self.nb_tri,self.tri]), self.nb_tri)
|
89
95
|
|
90
|
-
def from_polydata(self,poly:pv.PolyData):
|
96
|
+
def from_polydata(self, poly:pv.PolyData):
|
97
|
+
""" Convert a PyVista PolyData object to the triangulation format """
|
91
98
|
|
92
99
|
self.pts = np.asarray(poly.points.copy())
|
93
100
|
self.tri = np.asarray(poly.faces.reshape([int(len(poly.faces)/4),4])[:,1:4])
|
@@ -95,7 +102,8 @@ class Triangulation(Element_To_Draw):
|
|
95
102
|
self.nb_pts = len(self.pts)
|
96
103
|
self.nb_tri = len(self.tri)
|
97
104
|
|
98
|
-
def clip_surface(self,other,invert=True,subdivide=0):
|
105
|
+
def clip_surface(self, other:"Triangulation", invert=True, subdivide=0):
|
106
|
+
""" Clip the triangulation with another one """
|
99
107
|
|
100
108
|
if subdivide==0:
|
101
109
|
mypoly = self.as_polydata()
|
@@ -104,14 +112,12 @@ class Triangulation(Element_To_Draw):
|
|
104
112
|
mypoly = self.as_polydata().subdivide(subdivide)
|
105
113
|
mycrop = other.as_polydata().subdivide(subdivide)
|
106
114
|
|
107
|
-
res = mypoly.clip_surface(mycrop,invert=invert)
|
115
|
+
res = mypoly.clip_surface(mycrop, invert=invert)
|
108
116
|
|
109
117
|
if len(res.faces)>0:
|
110
118
|
self.from_polydata(res)
|
111
|
-
else:
|
112
|
-
return None
|
113
119
|
|
114
|
-
def get_mask(self,eps=1e-10):
|
120
|
+
def get_mask(self, eps:float= 1e-10):
|
115
121
|
"""
|
116
122
|
Teste si la surface de tous les triangles est positive
|
117
123
|
|
@@ -122,7 +128,7 @@ class Triangulation(Element_To_Draw):
|
|
122
128
|
v1 = [self.pts[curtri[1]][:2] - self.pts[curtri[0]][:2] for curtri in self.tri]
|
123
129
|
v2 = [self.pts[curtri[2]][:2] - self.pts[curtri[0]][:2] for curtri in self.tri]
|
124
130
|
self.areas = np.cross(v2,v1,)/2
|
125
|
-
return self.areas<=eps
|
131
|
+
return self.areas <= eps
|
126
132
|
|
127
133
|
# invalid_tri = np.sort(np.where(self.areas<=eps)[0])
|
128
134
|
# for curinv in invalid_tri[::-1]:
|
@@ -131,8 +137,11 @@ class Triangulation(Element_To_Draw):
|
|
131
137
|
# self.nb_tri = len(self.tri)
|
132
138
|
|
133
139
|
def import_from_gltf(self, fn=''):
|
140
|
+
""" Import a GLTF file and convert it to the triangulation format """
|
134
141
|
|
135
|
-
|
142
|
+
wx_exists = wx.GetApp() is not None
|
143
|
+
|
144
|
+
if fn =='' and wx_exists:
|
136
145
|
dlg=wx.FileDialog(None,_('Choose filename'),wildcard='binary gltf2 (*.glb)|*.glb|gltf2 (*.gltf)|*.gltf|All (*.*)|*.*',style=wx.FD_OPEN)
|
137
146
|
ret=dlg.ShowModal()
|
138
147
|
if ret==wx.ID_CANCEL:
|
@@ -141,6 +150,8 @@ class Triangulation(Element_To_Draw):
|
|
141
150
|
|
142
151
|
fn=dlg.GetPath()
|
143
152
|
dlg.Destroy()
|
153
|
+
else:
|
154
|
+
fn = str(fn)
|
144
155
|
|
145
156
|
gltf = pygltflib.GLTF2().load(fn)
|
146
157
|
|
@@ -216,6 +227,7 @@ class Triangulation(Element_To_Draw):
|
|
216
227
|
self.nb_tri = len(self.tri)
|
217
228
|
|
218
229
|
def export_to_gltf(self,fn=''):
|
230
|
+
""" Export the triangulation to a GLTF file """
|
219
231
|
|
220
232
|
#on force les types de variables
|
221
233
|
triangles = np.asarray(self.tri).astype(np.uint32)
|
@@ -302,7 +314,7 @@ class Triangulation(Element_To_Draw):
|
|
302
314
|
return
|
303
315
|
|
304
316
|
if fn!='':
|
305
|
-
self.filename=fn
|
317
|
+
self.filename = fn
|
306
318
|
|
307
319
|
triangles = np.asarray(self.tri).astype(np.uint32)
|
308
320
|
points = np.asarray(self.pts) #.astype(np.float64)
|
@@ -343,11 +355,13 @@ class Triangulation(Element_To_Draw):
|
|
343
355
|
buf = np.frombuffer(f.read(4 * self.nb_tri * 3), dtype=np.uint32)
|
344
356
|
self.tri = np.array(buf.copy(), dtype=np.uint32).reshape([self.nb_tri,3]).astype(np.int32)
|
345
357
|
|
346
|
-
self.
|
358
|
+
self.validate_format()
|
347
359
|
self.find_minmax(True)
|
348
360
|
self.reset_plot()
|
349
361
|
|
350
362
|
def reset_plot(self):
|
363
|
+
""" Reset the OpenGL plot """
|
364
|
+
|
351
365
|
try:
|
352
366
|
if self.id_list!=-99999:
|
353
367
|
glDeleteLists(self.id_list)
|
@@ -357,6 +371,7 @@ class Triangulation(Element_To_Draw):
|
|
357
371
|
self.id_list = -99999
|
358
372
|
|
359
373
|
def plot(self, sx=None, sy=None, xmin=None, ymin=None, xmax=None, ymax=None, size=None ):
|
374
|
+
""" Plot the triangulation in OpenGL """
|
360
375
|
|
361
376
|
if self.id_list == -99999:
|
362
377
|
try:
|
@@ -387,7 +402,25 @@ class Triangulation(Element_To_Draw):
|
|
387
402
|
else:
|
388
403
|
glCallList(self.id_list)
|
389
404
|
|
405
|
+
def plot_matplotlib(self, ax:Axes, color='black', alpha=1., lw=1.5, **kwargs):
|
406
|
+
""" Plot the triangulation in Matplotlib
|
407
|
+
"""
|
408
|
+
|
409
|
+
if self.nb_tri>0:
|
410
|
+
for curtri in self.tri:
|
411
|
+
x = [self.pts[curtri[0]][0], self.pts[curtri[1]][0], self.pts[curtri[2]][0], self.pts[curtri[0]][0]]
|
412
|
+
y = [self.pts[curtri[0]][1], self.pts[curtri[1]][1], self.pts[curtri[2]][1], self.pts[curtri[0]][1]]
|
413
|
+
ax.plot(x, y, color=color, alpha=alpha, lw=lw, **kwargs)
|
414
|
+
else:
|
415
|
+
logging.warning('No triangles to plot')
|
416
|
+
|
417
|
+
|
390
418
|
def find_minmax(self,force):
|
419
|
+
""" Find the min and max of the triangulation
|
420
|
+
|
421
|
+
:param force: force the min and max to be calculated
|
422
|
+
"""
|
423
|
+
|
391
424
|
if force:
|
392
425
|
if self.nb_pts>0:
|
393
426
|
self.xmin=np.min(self.pts[:,0])
|
@@ -396,6 +429,8 @@ class Triangulation(Element_To_Draw):
|
|
396
429
|
self.ymax=np.max(self.pts[:,1])
|
397
430
|
|
398
431
|
def import_dxf(self,fn):
|
432
|
+
""" Import a DXF file and convert it to the triangulation format """
|
433
|
+
|
399
434
|
import ezdxf
|
400
435
|
|
401
436
|
if not path.exists(fn):
|
@@ -431,7 +466,7 @@ class Triangulation(Element_To_Draw):
|
|
431
466
|
self.pts = xyz_u
|
432
467
|
self.nb_pts = len(self.pts)
|
433
468
|
self.nb_tri = len(self.tri)
|
434
|
-
self.
|
469
|
+
self.validate_format()
|
435
470
|
|
436
471
|
def set_cache(self):
|
437
472
|
""" Set the cache for the vertices """
|
@@ -4038,7 +4073,7 @@ class zone:
|
|
4038
4073
|
self.add_vector(mypl,0)
|
4039
4074
|
self.add_vector(mypr,2)
|
4040
4075
|
|
4041
|
-
def
|
4076
|
+
def create_multibin(self, nb:int = None, nb2:int = 0) -> Triangulation:
|
4042
4077
|
"""
|
4043
4078
|
Création d'une triangulation sur base des vecteurs
|
4044
4079
|
Tient compte de l'ordre
|
@@ -4075,7 +4110,11 @@ class zone:
|
|
4075
4110
|
nb=int(dlg.GetValue())
|
4076
4111
|
dlg.Destroy()
|
4077
4112
|
else:
|
4078
|
-
|
4113
|
+
try:
|
4114
|
+
nb=int(nb)
|
4115
|
+
except:
|
4116
|
+
logging.warning( _('Bad parameter nb'))
|
4117
|
+
return None
|
4079
4118
|
|
4080
4119
|
# redécoupage des polylines
|
4081
4120
|
s = np.linspace(0.,1.,num=nb,endpoint=True)
|
@@ -4095,10 +4134,16 @@ class zone:
|
|
4095
4134
|
ret=dlg.ShowModal()
|
4096
4135
|
if ret==wx.ID_CANCEL:
|
4097
4136
|
dlg.Destroy()
|
4098
|
-
return
|
4137
|
+
return None
|
4099
4138
|
|
4100
4139
|
nb2=int(dlg.GetValue())
|
4101
4140
|
dlg.Destroy()
|
4141
|
+
else:
|
4142
|
+
try:
|
4143
|
+
nb2=int(nb2)
|
4144
|
+
except:
|
4145
|
+
logging.warning( _('Bad parameter nb2'))
|
4146
|
+
return None
|
4102
4147
|
|
4103
4148
|
if nb2>0:
|
4104
4149
|
finalls = []
|
@@ -4187,9 +4232,12 @@ class zone:
|
|
4187
4232
|
|
4188
4233
|
return interp
|
4189
4234
|
|
4190
|
-
def create_constrainedDelaunay(self, nb=None) -> Triangulation:
|
4235
|
+
def create_constrainedDelaunay(self, nb:int = None) -> Triangulation:
|
4191
4236
|
"""
|
4192
|
-
Création d'une triangulation Delaunay contrainte sur base des vecteurs
|
4237
|
+
Création d'une triangulation Delaunay contrainte sur base des vecteurs de la zone.
|
4238
|
+
|
4239
|
+
Il est nécessaire de définir au moins un polygone définissant la zone de triangulation.
|
4240
|
+
Les autres vecteurs seront utilisés comme contraintes de triangulation.
|
4193
4241
|
|
4194
4242
|
Utilisation de la librairie "triangle" (https://www.cs.cmu.edu/~quake/triangle.delaunay.html)
|
4195
4243
|
|
@@ -4223,14 +4271,18 @@ class zone:
|
|
4223
4271
|
nb=int(dlg.GetValue())
|
4224
4272
|
dlg.Destroy()
|
4225
4273
|
else:
|
4226
|
-
|
4274
|
+
try:
|
4275
|
+
nb=int(nb)
|
4276
|
+
except:
|
4277
|
+
logging.warning( _('Bad parameter nb'))
|
4278
|
+
return None
|
4227
4279
|
|
4228
4280
|
if nb==0:
|
4229
4281
|
# no decimation
|
4230
4282
|
newls = myls
|
4231
4283
|
else:
|
4232
4284
|
# redécoupage des polylines
|
4233
|
-
s = np.linspace(0.,1.,num=nb,endpoint=True)
|
4285
|
+
s = np.linspace(0., 1., num=nb, endpoint=True)
|
4234
4286
|
|
4235
4287
|
newls = [LineString([curls.interpolate(curs,True) for curs in s]) for curls in myls if curls.length>0.]
|
4236
4288
|
|
@@ -7690,7 +7742,7 @@ class Zones(wx.Frame, Element_To_Draw):
|
|
7690
7742
|
dlg.Destroy()
|
7691
7743
|
return
|
7692
7744
|
|
7693
|
-
mytri = myzone.
|
7745
|
+
mytri = myzone.create_multibin()
|
7694
7746
|
|
7695
7747
|
self.mapviewer.add_object('triangulation',newobj=mytri)
|
7696
7748
|
self.mapviewer.Refresh()
|