wolfhece 2.2.36__py3-none-any.whl → 2.2.38__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 CHANGED
@@ -12229,6 +12229,46 @@ class WolfMapViewer(wx.Frame):
12229
12229
  self.selected_object.active_vector.parentzone.add_vector(vec_raster, forceparent=True, update_struct=True)
12230
12230
  self.selected_object.active_vector.parentzone.reset_listogl()
12231
12231
 
12232
+ elif _('Extrude on active array') in text:
12233
+
12234
+ if isinstance(self.selected_object, Picc_data):
12235
+
12236
+ if self.active_array is None:
12237
+ logging.warning(_('No active array selected'))
12238
+ return
12239
+
12240
+ logging.info(_('Extruding polygons on active array'))
12241
+ logging.info(_('Please wait, it could take some time...'))
12242
+ self.selected_object.extrude_polygons(self.active_array)
12243
+ logging.info(_('Extrusion done !'))
12244
+
12245
+ self.active_array.reset_plot()
12246
+ self.Refresh()
12247
+
12248
+ elif _('Interpolate on active array') in text:
12249
+
12250
+ if isinstance(self.selected_object, Zones):
12251
+
12252
+ if self.active_array is None:
12253
+ logging.warning(_('No active array selected'))
12254
+ return
12255
+
12256
+ dlg = wx.SingleChoiceDialog(None, _('With respect to the array values, keep the extruded values which are ?'), _('Interpolate on active array'), ['Above', 'Below', 'All'], style=wx.CHOICEDLG_STYLE)
12257
+ ret = dlg.ShowModal()
12258
+ if ret != wx.ID_OK:
12259
+ dlg.Destroy()
12260
+ return
12261
+ choice = dlg.GetStringSelection().lower()
12262
+ dlg.Destroy()
12263
+
12264
+
12265
+ logging.info(_('Interpolating polygons on active array'))
12266
+ logging.info(_('Please wait, it could take some time...'))
12267
+ for curzone in self.selected_object.myzones:
12268
+ self.active_array.interpolate_on_polygons(curzone, keep = choice)
12269
+ logging.info(_('Interpolation done !'))
12270
+
12271
+
12232
12272
  def OnClose(self, event):
12233
12273
  """ Close the application """
12234
12274
 
@@ -12292,6 +12332,7 @@ class WolfMapViewer(wx.Frame):
12292
12332
  nameitem = self.treelist.GetItemText(myitem).lower()
12293
12333
 
12294
12334
  ctrl = wx.GetKeyState(wx.WXK_CONTROL)
12335
+ shiftdown = wx.GetKeyState(wx.WXK_SHIFT)
12295
12336
 
12296
12337
  # ctrl = event.ControlDown()
12297
12338
 
@@ -12345,6 +12386,8 @@ class WolfMapViewer(wx.Frame):
12345
12386
  else:
12346
12387
  if issubclass(type(curobj), WolfArray):
12347
12388
  curobj.uncheck_plot(not ctrl,ctrl)
12389
+ elif isinstance(curobj, Picc_data):
12390
+ curobj.uncheck_plot(ctrl, shiftdown)
12348
12391
  else:
12349
12392
  curobj.uncheck_plot()
12350
12393
 
@@ -15157,6 +15200,9 @@ class WolfMapViewer(wx.Frame):
15157
15200
  tracks.append(_('Rasterize active zone'))
15158
15201
  tracks.append(_('Rasterize active vector'))
15159
15202
 
15203
+ tracks.append(_('Extrude on active array'))
15204
+ tracks.append(_('Interpolate on active array'))
15205
+
15160
15206
  # Récupération des items du menu contextuel
15161
15207
  menuitems = self.popupmenu.GetMenuItems()
15162
15208
  text = [cur.GetItemLabelText() for cur in menuitems]
@@ -15197,6 +15243,7 @@ class WolfMapViewer(wx.Frame):
15197
15243
  if isinstance(self.selected_object, Zones):
15198
15244
  self.popupmenu.Append(wx.ID_ANY, _('Rasterize active zone'), _('Rasterize active zone'))
15199
15245
  self.popupmenu.Append(wx.ID_ANY, _('Rasterize active vector'), _('Rasterize active vector'))
15246
+ self.popupmenu.Append(wx.ID_ANY, _('Interpolate on active array'), _('Interpolate Z-values on active array'))
15200
15247
 
15201
15248
  if isinstance(self.selected_object, Zones | Bridge | Weir):
15202
15249
  self.popupmenu.Append(wx.ID_ANY, _('Export to Shape file'), _('Export to Shape file'))
@@ -15229,6 +15276,9 @@ class WolfMapViewer(wx.Frame):
15229
15276
  moviemenu.Append(wx.ID_ANY, _('Load flight'), _('Load flight'))
15230
15277
  moviemenu.Append(wx.ID_ANY, _('Save flight'), _('Save flight'))
15231
15278
 
15279
+ if isinstance(self.selected_object, Picc_data):
15280
+ self.popupmenu.Append(wx.ID_ANY, _('Extrude on active array'), _('Extrude building elevation on active array'))
15281
+
15232
15282
  self.treelist.PopupMenu(self.popupmenu)
15233
15283
 
15234
15284
  def zoom_on_whole_walonia(self):
wolfhece/PyVertex.py CHANGED
@@ -1061,6 +1061,13 @@ class cloud_vertices(Element_To_Draw):
1061
1061
 
1062
1062
  if self.myprop.legendvisible:
1063
1063
 
1064
+ dx = xmax - xmin
1065
+ dy = ymax - ymin
1066
+
1067
+ if dx > 50_000. or dy > 50_000.:
1068
+ logging.warning(_('Too large bounds for legend plot -- skipping'))
1069
+ return
1070
+
1064
1071
  mapviewer = self.get_mapviewer()
1065
1072
 
1066
1073
  which_legend = self.myprop.legendtext
@@ -1336,6 +1336,8 @@ class vector:
1336
1336
  self._lengthparts2D=None
1337
1337
  self._lengthparts3D=None
1338
1338
 
1339
+ self._simplified_geometry = False
1340
+
1339
1341
  if type(lines)==list:
1340
1342
  if len(lines)>0:
1341
1343
  self.myname=lines[0]
@@ -2276,6 +2278,43 @@ class vector:
2276
2278
 
2277
2279
  return len(not_in_use) > 0
2278
2280
 
2281
+ def check_if_interior_exists(self):
2282
+ """ Check if the vector has an interior and adapt in_use accordingly.
2283
+
2284
+ The verification is only made in 2D, as the interior is defined as a pair of segments that correspond exactly to the same coordinates.
2285
+ Z coordinates are not taken into account in this verification.
2286
+
2287
+ """
2288
+
2289
+ xy = self.xy
2290
+ if self.closed and (xy[0,0] == xy[-1,0] and xy[0,1] == xy[-1,1]):
2291
+ # If the vector is closed, we remove the last vertex to avoid checking it
2292
+ xy = xy[:-1]
2293
+
2294
+ xy_unique, inverse, count = np.unique(xy, return_inverse=True, return_counts=True, axis=0)
2295
+
2296
+ duplicate_found = False
2297
+
2298
+ if xy.shape[0] != xy_unique.shape[0]:
2299
+ # There are duplicates, we need to test if the duplicate form a segment
2300
+
2301
+ # Find the duplicate indices
2302
+ duplicate_indices = np.where(count > 1)[0]
2303
+ # Find the inverse indices of the duplicates
2304
+ duplicate_indices = np.where(np.isin(inverse, duplicate_indices))[0]
2305
+ diff = np.diff(duplicate_indices)
2306
+
2307
+ for i in range(len(diff)):
2308
+ # Set the in_use property to False for the vertices that are not used
2309
+ if diff[i] == 1:
2310
+ self.myvertices[duplicate_indices[i+1]].in_use = False
2311
+ duplicate_found = True
2312
+
2313
+ if duplicate_found:
2314
+ self.reset_linestring()
2315
+ self._reset_listogl()
2316
+
2317
+
2279
2318
  @property
2280
2319
  def nb_interiors(self) -> int:
2281
2320
  """ Return the number of interiors in the vector.
@@ -2336,10 +2375,32 @@ class vector:
2336
2375
  return tri.get_triangles_as_listwolfvertices()
2337
2376
 
2338
2377
  else:
2339
- if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
2340
- return [self.myvertices + [self.myvertices[0]]]
2378
+ if self._simplified_geometry:
2379
+ if self.myprop.closed and (self.myvertices[0].x != self.myvertices[-1].x or self.myvertices[0].y != self.myvertices[-1].y):
2380
+ return [self.myvertices + [self.myvertices[0]]]
2381
+ else:
2382
+ return [self.myvertices]
2341
2383
  else:
2342
- return [self.myvertices]
2384
+ xx, yy = self.polygon.exterior.xy
2385
+
2386
+ # On translate les coordonnées pour éviter les erreurs de triangulation
2387
+ tr_x = np.array(xx).min()
2388
+ tr_y = np.array(yy).min()
2389
+
2390
+ xx = np.array(xx)-tr_x
2391
+ yy = np.array(yy)-tr_y
2392
+
2393
+ 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]]}
2394
+
2395
+ try:
2396
+ delaunay = triangle.triangulate(geom, 'p')
2397
+ tri = []
2398
+ for curtri in delaunay['triangles']:
2399
+ # on traduit les coordonnées pour revenir dans le monde réel
2400
+ tri.append([wolfvertex(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y) for i in range(3)])
2401
+ return tri
2402
+ except:
2403
+ pass
2343
2404
 
2344
2405
  else:
2345
2406
  if self.has_interior:
@@ -2509,28 +2570,35 @@ class vector:
2509
2570
  logging.debug(_('Polygon not in Polygon'))
2510
2571
 
2511
2572
  else:
2512
- #En attendant de lier WOLF-Fortran, on utilise la triangulation contrainte de la librairie Triangle -- https://rufat.be/triangle/
2513
- xx, yy = ls.exterior.xy
2514
-
2515
- # On translate les coordonnées pour éviter les erreurs de triangulation
2516
- tr_x = np.array(xx).min()
2517
- tr_y = np.array(yy).min()
2518
-
2519
- xx = np.array(xx)-tr_x
2520
- yy = np.array(yy)-tr_y
2521
-
2522
- 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]]}
2523
-
2524
- try:
2525
- delaunay = triangle.triangulate(geom, 'p')
2526
- for curtri in delaunay['triangles']:
2527
- glBegin(GL_POLYGON)
2528
- for i in range(3):
2529
- # on retraduit les coordonnées pour revenir dans le monde réel
2530
- glVertex2d(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y)
2531
- glEnd()
2532
- except:
2533
- pass
2573
+ # #En attendant de lier WOLF-Fortran, on utilise la triangulation contrainte de la librairie Triangle -- https://rufat.be/triangle/
2574
+ # xx, yy = ls.exterior.xy
2575
+
2576
+ # # On translate les coordonnées pour éviter les erreurs de triangulation
2577
+ # tr_x = np.array(xx).min()
2578
+ # tr_y = np.array(yy).min()
2579
+
2580
+ # xx = np.array(xx)-tr_x
2581
+ # yy = np.array(yy)-tr_y
2582
+
2583
+ # 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]]}
2584
+
2585
+ # try:
2586
+ # delaunay = triangle.triangulate(geom, 'p')
2587
+ # for curtri in delaunay['triangles']:
2588
+ # glBegin(GL_POLYGON)
2589
+ # for i in range(3):
2590
+ # # on retraduit les coordonnées pour revenir dans le monde réel
2591
+ # glVertex2d(delaunay['vertices'][curtri[i]][0] + tr_x, delaunay['vertices'][curtri[i]][1] + tr_y)
2592
+ # glEnd()
2593
+ # except:
2594
+ # pass
2595
+
2596
+ all_polys = self.get_subpolygons()
2597
+ for curpoly in all_polys:
2598
+ glBegin(GL_POLYGON)
2599
+ for curvertex in curpoly:
2600
+ glVertex2d(curvertex.x, curvertex.y)
2601
+ glEnd()
2534
2602
 
2535
2603
  else:
2536
2604
  all_polys = self.get_subpolygons()
@@ -2975,6 +3043,28 @@ class vector:
2975
3043
  gridto.SetCellValue(k,5,'1' if curv.in_use else '0')
2976
3044
  k+=1
2977
3045
 
3046
+ def _fillgrid_only_i(self, gridto:CpGrid):
3047
+ """
3048
+ Remplissage d'un CpGrid
3049
+ """
3050
+ curv:wolfvertex
3051
+
3052
+ gridto.SetColLabelValue(0,'X')
3053
+ gridto.SetColLabelValue(1,'Y')
3054
+ gridto.SetColLabelValue(2,'Z')
3055
+ gridto.SetColLabelValue(3,'value')
3056
+ gridto.SetColLabelValue(4,'s curvi')
3057
+ gridto.SetColLabelValue(5,'in use')
3058
+
3059
+ nb=gridto.GetNumberRows()
3060
+ if len(self.myvertices)-nb>0:
3061
+ gridto.AppendRows(len(self.myvertices)-nb)
3062
+ k=0
3063
+
3064
+ for curv in self.myvertices:
3065
+ gridto.SetCellValue(k, 5, '1' if curv.in_use else '0')
3066
+ k+=1
3067
+
2978
3068
  def updatefromgrid(self,gridfrom:CpGrid):
2979
3069
  """
2980
3070
  Mise à jour depuis un CpGrid
@@ -3435,6 +3525,12 @@ class vector:
3435
3525
  self.myprop.legendy = centroid.y
3436
3526
  self.myprop.legendtext = text if text else self.myname
3437
3527
 
3528
+ def set_legend_visible(self, visible:bool=True):
3529
+ """
3530
+ Set the visibility of the legend.
3531
+ """
3532
+ self.myprop.legendvisible = visible
3533
+
3438
3534
  def set_legend_position_to_centroid(self):
3439
3535
  """
3440
3536
  Positionne la légende au centre du vecteur
@@ -4045,6 +4141,11 @@ class zone:
4045
4141
  # Object can be created from a shapely object
4046
4142
  self.import_shapelyobj(fromshapely)
4047
4143
 
4144
+ def check_if_interior_exists(self):
4145
+ """ Check if the zone has at least one vector with interior points """
4146
+
4147
+ list(map(lambda curvec: curvec.check_if_interior_exists(), self.myvectors))
4148
+
4048
4149
  def add_values(self, key:str, values:np.ndarray):
4049
4150
  """ add values to the zone """
4050
4151
 
@@ -4052,8 +4153,7 @@ class zone:
4052
4153
  logging.warning(_('Number of vectors and values do not match'))
4053
4154
  return
4054
4155
 
4055
- for curvec, curval in zip(self.myvectors, values):
4056
- curvec.add_value(key, curval)
4156
+ list(map(lambda cur: cur[0].add_value(key, cur[1]), zip(self.myvectors, values)))
4057
4157
 
4058
4158
  def get_values(self, key:str) -> np.ndarray:
4059
4159
  """ get values from the zone """
@@ -4063,25 +4163,21 @@ class zone:
4063
4163
  def set_colors_from_value(self, key:str, cmap:wolfpalette | Colormap | cm.ScalarMappable, vmin:float= 0., vmax:float= 1.):
4064
4164
  """ Set the colors for the zone """
4065
4165
 
4066
- for curvec in self.myvectors:
4067
- curvec.set_color_from_value(key, cmap, vmin, vmax)
4166
+ list(map(lambda curvec: curvec.set_color_from_value(key, cmap, vmin, vmax), self.myvectors))
4068
4167
 
4069
4168
  def set_alpha(self, alpha:int):
4070
4169
  """ Set the alpha for the zone """
4071
4170
 
4072
- for curvec in self.myvectors:
4073
- curvec.set_alpha(alpha)
4171
+ list(map(lambda curvec: curvec.set_alpha(alpha), self.myvectors))
4074
4172
 
4075
4173
  def set_filled(self, filled:bool):
4076
4174
  """ Set the filled for the zone """
4077
4175
 
4078
- for curvec in self.myvectors:
4079
- curvec.set_filled(filled)
4176
+ list(map(lambda curvec: curvec.set_filled(filled), self.myvectors))
4080
4177
 
4081
4178
  def check_if_open(self):
4082
4179
  """ Check if the vectors in the zone are open """
4083
- for curvec in self.myvectors:
4084
- curvec.check_if_open()
4180
+ list(map(lambda curvect: curvect.check_if_open(), self.myvectors))
4085
4181
 
4086
4182
  def buffer(self, distance:float, resolution:int=16, inplace:bool = False) -> 'zone':
4087
4183
  """ Create a new zone with a buffer around each vector """
@@ -4106,24 +4202,21 @@ class zone:
4106
4202
  Set the legend text for the zone
4107
4203
  """
4108
4204
 
4109
- for curvect in self.myvectors:
4110
- curvect.set_legend_text(text)
4205
+ list(map(lambda curvect: curvect.set_legend_text(text), self.myvectors))
4111
4206
 
4112
4207
  def set_legend_text_from_values(self, key:str):
4113
4208
  """
4114
4209
  Set the legend text for the zone from a value
4115
4210
  """
4116
4211
 
4117
- for curvect in self.myvectors:
4118
- curvect.set_legend_text_from_value(key)
4212
+ list(map(lambda curvect: curvect.set_legend_text_from_value(key), self.myvectors))
4213
+
4119
4214
 
4120
4215
  def set_legend_position(self, x, y):
4121
4216
  """
4122
4217
  Set the legend position for the zone
4123
4218
  """
4124
-
4125
- for curvect in self.myvectors:
4126
- curvect.set_legend_position(x, y)
4219
+ list(map(lambda curvect: curvect.set_legend_position(x, y), self.myvectors))
4127
4220
 
4128
4221
  @property
4129
4222
  def area(self):
@@ -4139,15 +4232,14 @@ class zone:
4139
4232
  """
4140
4233
  Set the cache for the zone and all its vectors
4141
4234
  """
4142
- for curvect in self.myvectors:
4143
- curvect.set_cache()
4235
+
4236
+ list(map(lambda curvect: curvect.set_cache(), self.myvectors))
4144
4237
 
4145
4238
  def clear_cache(self):
4146
4239
  """
4147
4240
  Clear the cache for the zone and all its vectors
4148
4241
  """
4149
- for curvect in self.myvectors:
4150
- curvect.clear_cache()
4242
+ list(map(lambda curvect: curvect.clear_cache(), self.myvectors))
4151
4243
 
4152
4244
  self._move_start = None
4153
4245
  self._move_step = None
@@ -4507,8 +4599,9 @@ class zone:
4507
4599
  else:
4508
4600
  fig = ax.figure
4509
4601
 
4510
- for curvect in self.myvectors:
4511
- curvect.plot_matplotlib(ax)
4602
+ # for curvect in self.myvectors:
4603
+ # curvect.plot_matplotlib(ax)
4604
+ list(map(lambda curvect: curvect.plot_matplotlib(ax), self.myvectors))
4512
4605
 
4513
4606
  return fig, ax
4514
4607
 
@@ -6199,9 +6292,13 @@ class zone:
6199
6292
  """
6200
6293
  Set the legend to the centroid of the vectors
6201
6294
  """
6295
+ list(map(lambda curvec: curvec.set_legend_to_centroid(), self.myvectors))
6202
6296
 
6203
- for curvec in self.myvectors:
6204
- curvec.set_legend_position_to_centroid()
6297
+ def set_legend_visible(self, visible:bool=True):
6298
+ """
6299
+ Set the visibility of the legend for all vectors in the zone
6300
+ """
6301
+ list(map(lambda curvec: curvec.set_legend_visible(visible), self.myvectors))
6205
6302
 
6206
6303
  class Zones(wx.Frame, Element_To_Draw):
6207
6304
  """
@@ -6410,6 +6507,11 @@ class Zones(wx.Frame, Element_To_Draw):
6410
6507
 
6411
6508
  return [curzone.myname for curzone in self.myzones]
6412
6509
 
6510
+ def check_if_interior_exists(self):
6511
+ """ Check if the zone has at least one vector with interior points """
6512
+ for curzone in self.myzones:
6513
+ curzone.check_if_interior_exists()
6514
+
6413
6515
  def add_values(self, key:str, values:np.ndarray | dict):
6414
6516
  """
6415
6517
  Add values to the zones
@@ -6910,7 +7012,7 @@ class Zones(wx.Frame, Element_To_Draw):
6910
7012
  curvect.myprop.color = curcolor
6911
7013
  curvect.myprop.alpha = 180
6912
7014
  curvect.myprop.transparent = True
6913
- curvect.myprop.filled = filled
7015
+ curvect.myprop.filled = filled and curvect.closed
6914
7016
 
6915
7017
  def set_width(self, width:int) -> None:
6916
7018
  """ Change with of all vectors in all zones """
@@ -7351,6 +7453,10 @@ class Zones(wx.Frame, Element_To_Draw):
7351
7453
  self.updatevertices.SetToolTip(_("Transfer the coordinates from the editor to the memory and update the plot"))
7352
7454
  self.updatevertices.Bind(wx.EVT_BUTTON,self.Onupdatevertices)
7353
7455
 
7456
+ self._test_interior = wx.Button(self,label=_('Test interior'))
7457
+ self._test_interior.SetToolTip(_("Test if some segments of the active vector are exactly the same"))
7458
+ self._test_interior.Bind(wx.EVT_BUTTON,self.Ontest_interior)
7459
+
7354
7460
  self.plot_mpl = wx.Button(self,label=_('Plot xy'))
7355
7461
  self.plot_mpl.SetToolTip(_("Plot the active vector in a new window (matplotlib)"))
7356
7462
  self.plot_mpl.Bind(wx.EVT_BUTTON,self.Onplotmpl)
@@ -7360,7 +7466,7 @@ class Zones(wx.Frame, Element_To_Draw):
7360
7466
  self.plot_mplsz.Bind(wx.EVT_BUTTON,self.Onplotmplsz)
7361
7467
 
7362
7468
  sizer_add_update.Add(self.addrows,1, wx.EXPAND)
7363
- sizer_add_update.Add(self.updatevertices,3, wx.EXPAND)
7469
+ sizer_add_update.Add(self.updatevertices, 1, wx.EXPAND)
7364
7470
  sizer_add_update.Add(self.plot_mpl,1, wx.EXPAND)
7365
7471
  sizer_add_update.Add(self.plot_mplsz,1, wx.EXPAND)
7366
7472
 
@@ -7516,6 +7622,8 @@ class Zones(wx.Frame, Element_To_Draw):
7516
7622
 
7517
7623
  box_interp_indices = wx.BoxSizer(wx.HORIZONTAL)
7518
7624
  box_interp_indices.Add(self.interpxyz,1,wx.EXPAND)
7625
+ box_interp_indices.Add(self._test_interior, 1, wx.EXPAND)
7626
+
7519
7627
 
7520
7628
  boxright.Add(box_interp_indices,0,wx.EXPAND)
7521
7629
 
@@ -7691,7 +7799,7 @@ class Zones(wx.Frame, Element_To_Draw):
7691
7799
  self.fill_structure()
7692
7800
 
7693
7801
  self.treelist.SetSize(200,500)
7694
- self.SetSize(600,700)
7802
+ self.SetSize(650,700)
7695
7803
 
7696
7804
  self.SetSizer(box)
7697
7805
 
@@ -9062,6 +9170,18 @@ class Zones(wx.Frame, Element_To_Draw):
9062
9170
  self.active_vector.updatefromgrid(self.xls)
9063
9171
  self.find_minmax(True)
9064
9172
 
9173
+ def Ontest_interior(self, event:wx.MouseEvent):
9174
+ """ Test if the active vector has interior portions """
9175
+ if self.verify_activevec():
9176
+ return
9177
+
9178
+ self.active_vector.check_if_interior_exists()
9179
+
9180
+ self.active_vector._fillgrid_only_i(self.xls)
9181
+
9182
+ self.get_mapviewer().Paint()
9183
+
9184
+
9065
9185
  def Onplotmpl(self, event:wx.MouseEvent):
9066
9186
  """
9067
9187
  Plot active vector in matplotlib
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 2
8
- self.patch = 36
8
+ self.patch = 38
9
9
 
10
10
  def __str__(self):
11
11