wolfhece 2.1.109__py3-none-any.whl → 2.1.110__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wolfhece/PyDraw.py CHANGED
@@ -116,6 +116,12 @@ except ImportError as e:
116
116
  print(e)
117
117
  raise ImportError("Error importing pyshields, pyviews, PyConfig, GraphProfile, pybridges, tools_mpl, wolf_tiles, lagrangian.particle_system_ui, opengl.py3d, pyGui1D. Please check your installation.")
118
118
 
119
+ try:
120
+ from .apps.curvedigitizer import Digitizer
121
+ except ImportError as e:
122
+ print(e)
123
+ raise ImportError("Error importing apps.curvedigitizer. Please check your installation.")
124
+
119
125
  ID_SELECTCS = 1000
120
126
  ID_SORTALONG = 1001
121
127
  ID_LOCMINMAX = 1002
@@ -1363,6 +1369,7 @@ class WolfMapViewer(wx.Frame):
1363
1369
  self.menu_contour_from_arrays = self.tools_menu.Append(wx.ID_ANY, _("Create contour from checked arrays..."), _("Create contour"))
1364
1370
  self.menu_calculator = self.tools_menu.Append(wx.ID_ANY, _("Calculator..."), _("Calculator"))
1365
1371
  self.menu_views = self.tools_menu.Append(wx.ID_ANY, _("Memory views..."), _("Memory views"))
1372
+ self.menu_digitizer = self.tools_menu.Append(wx.ID_ANY, _("Image digitizer..."), _("Image Digitizer"))
1366
1373
  self.calculator = None
1367
1374
  self.memory_views = None
1368
1375
  self._memory_views_gui = None
@@ -1708,6 +1715,8 @@ class WolfMapViewer(wx.Frame):
1708
1715
 
1709
1716
  self._menuinteractptri = self.trianglesmenu.Append(wx.ID_ANY, _("Interpolate on active triangulation..."), _("InterpolateTri"))
1710
1717
  self._menucomparetri = self.trianglesmenu.Append(wx.ID_ANY, _("Compare triangles to array..."), _("Comparison"))
1718
+ self._menumovetri = self.trianglesmenu.Append(wx.ID_ANY, _("Move triangles..."), _("Move triangles"))
1719
+ self._menurotatetri = self.trianglesmenu.Append(wx.ID_ANY, _("Rotate triangles..."), _("Rotate triangles"))
1711
1720
 
1712
1721
 
1713
1722
  def create_cloud_menu(self):
@@ -3143,6 +3152,20 @@ class WolfMapViewer(wx.Frame):
3143
3152
 
3144
3153
  self.active_array.compare_tri(self.active_tri)
3145
3154
 
3155
+ def move_triangles(self):
3156
+ """ Move the active triangles """
3157
+ if self.active_tri is None:
3158
+ logging.warning(_('No active triangles -- Please activate triangles first'))
3159
+ return
3160
+ self.start_action('move triangles', 'Move the current triangulation -- Please select 2 points to define the translation vector')
3161
+
3162
+ def rotate_triangles(self):
3163
+ """ Rotate the active triangles """
3164
+ if self.active_tri is None:
3165
+ logging.warning(_('No active triangles -- Please activate triangles first'))
3166
+ return
3167
+ self.start_action('rotate triangles', 'Rotate the current triangulation -- Please select 1 point for the center')
3168
+
3146
3169
  def copy_canvasogl(self, mpl:bool= True, ds:float= 0., figsizes= [10.,10.], palette:wolfpalette = None):
3147
3170
  """
3148
3171
  Generate image based on UI context and copy to the Clipboard
@@ -6270,6 +6293,14 @@ class WolfMapViewer(wx.Frame):
6270
6293
  autoscale = False
6271
6294
  self.compare_tri2array()
6272
6295
 
6296
+ elif itemlabel == _("Move triangles..."):
6297
+ autoscale = False
6298
+ self.move_triangles()
6299
+
6300
+ elif itemlabel == _("Rotate triangles..."):
6301
+ autoscale = False
6302
+ self.rotate_triangles()
6303
+
6273
6304
  elif itemlabel == _("Create contour from checked arrays..."):
6274
6305
  autoscale = False
6275
6306
 
@@ -6285,6 +6316,11 @@ class WolfMapViewer(wx.Frame):
6285
6316
  else:
6286
6317
  self.calculator.Show()
6287
6318
 
6319
+ elif itemlabel == _('Image digitizer...'):
6320
+ autoscale = False
6321
+
6322
+ new_digitizer = Digitizer()
6323
+
6288
6324
  elif itemlabel == _("Memory views..."):
6289
6325
  autoscale = False
6290
6326
 
@@ -9042,6 +9078,54 @@ class WolfMapViewer(wx.Frame):
9042
9078
 
9043
9079
  self.rightdown = (x, y)
9044
9080
 
9081
+ elif self.action == 'move triangles':
9082
+
9083
+ if self.active_tri is None:
9084
+ logging.warning(_('No triangles selected -- Please select a triangulation first !'))
9085
+ return
9086
+
9087
+ if self.active_tri._start_move is None:
9088
+ self.active_tri._start_move = (x, y)
9089
+ return
9090
+
9091
+ delta_x = x - self.active_tri._start_move[0]
9092
+ delta_y = y - self.active_tri._start_move[1]
9093
+
9094
+ if shiftdown:
9095
+ delta_y = 0.
9096
+
9097
+ if alt:
9098
+ delta_x = 0.
9099
+
9100
+ self.active_tri.move(delta_x, delta_y)
9101
+ self.active_tri.reset_plot()
9102
+ self.active_tri._start_move = None
9103
+ self.active_tri.clear_cache()
9104
+ self.end_action(_('End move triangulation'))
9105
+
9106
+ elif self.action == 'rotate triangles':
9107
+
9108
+ if self.active_tri is None:
9109
+ logging.warning(_('No vector selected -- Please select a triangulation first !'))
9110
+ return
9111
+
9112
+ if self.active_tri._rotation_center is None:
9113
+ self.active_tri._rotation_center = (x,y)
9114
+ return
9115
+
9116
+ if shiftdown:
9117
+ if ctrl:
9118
+ self.active_tri._rotation_step = None
9119
+ else:
9120
+ # Set the rotation step
9121
+ self.active_tri._rotation_step = np.degrees(np.arctan2(y - self.active_tri._rotation_center[1], x - self.active_tri._rotation_center[0]))
9122
+
9123
+ self.active_tri.rotate_xy(x, y)
9124
+ self.active_tri._rotation_center = None
9125
+ self.active_tri.clear_cache()
9126
+ self.active_tri.reset_plot()
9127
+ self.end_action(_('End rotate triangulation'))
9128
+
9045
9129
  elif 'pick landmap' in self.action:
9046
9130
  # Pick a landmap if loaded
9047
9131
 
@@ -9989,11 +10073,34 @@ class WolfMapViewer(wx.Frame):
9989
10073
 
9990
10074
  self.active_vector.move(delta_x, delta_y)
9991
10075
 
10076
+ if self.action == 'move triangles':
10077
+ if self.active_tri is not None:
10078
+ if self.active_tri._start_move is not None:
10079
+
10080
+ delta_x = x - self.active_tri._start_move[0]
10081
+ delta_y = y - self.active_tri._start_move[1]
10082
+
10083
+ if shiftdown:
10084
+ delta_y = 0.
10085
+
10086
+ if altdown:
10087
+ delta_x = 0.
10088
+
10089
+ self.active_tri.move(delta_x, delta_y)
10090
+
10091
+ self.active_tri.reset_plot()
10092
+
9992
10093
  if self.action == 'rotate vector':
9993
10094
  if self.active_vector is not None:
9994
10095
  if self.active_vector._rotation_center is not None:
9995
10096
  self.active_vector.rotate_xy(x, y)
9996
10097
 
10098
+ if self.action == 'rotate triangles':
10099
+ if self.active_tri is not None:
10100
+ if self.active_tri._rotation_center is not None:
10101
+ self.active_tri.rotate_xy(x, y)
10102
+ self.active_tri.reset_plot()
10103
+
9997
10104
  if self.action == 'move zone':
9998
10105
  if self.active_zone is not None:
9999
10106
  if self.active_zone._start_move is not None:
@@ -59,6 +59,12 @@ class Triangulation(Element_To_Draw):
59
59
  self.nb_tri = len(tri)
60
60
  self.nb_pts = len(pts)
61
61
 
62
+ self._start_move = None
63
+ self._move_step = None # step for a move
64
+ self._rotation_center = None
65
+ self._rotation_step = None
66
+ self._cache = None
67
+
62
68
  if fn !='':
63
69
  self.filename=fn
64
70
  self.read(fn)
@@ -370,6 +376,7 @@ class Triangulation(Element_To_Draw):
370
376
  glPolygonMode(GL_FRONT_AND_BACK,GL_LINE)
371
377
 
372
378
  glEndList()
379
+ glCallList(self.id_list)
373
380
  except:
374
381
  logging.warning('Problem with OpenGL plot - Triangulation.plot')
375
382
  else:
@@ -420,6 +427,67 @@ class Triangulation(Element_To_Draw):
420
427
  self.nb_pts = len(self.pts)
421
428
  self.nb_tri = len(self.tri)
422
429
  self.valid_format()
430
+
431
+ def set_cache(self):
432
+ """ Set the cache for the vertices """
433
+
434
+ self._cache = self.pts.copy()
435
+
436
+ def clear_cache(self):
437
+ """ Clear the cache for the vertices """
438
+
439
+ self._cache = None
440
+
441
+ def move(self, delta_x:float, delta_y:float, use_cache:bool = True):
442
+ """ Move the vertices by a delta_x and delta_y
443
+
444
+ :param delta_x: delta x [m]
445
+ :param delta_y: delta y [m]
446
+ """
447
+
448
+ if use_cache and self._cache is None:
449
+ self.set_cache()
450
+
451
+ if use_cache:
452
+ self.pts[:,0] = self._cache[:,0] + delta_x
453
+ self.pts[:,1] = self._cache[:,1] + delta_y
454
+ else:
455
+ self.pts[:,0] += delta_x
456
+ self.pts[:,1] += delta_y
457
+
458
+ def rotate(self, angle:float, center:tuple, use_cache:bool = True):
459
+ """ Rotate the vertices around a center
460
+
461
+ :param angle: angle in degrees -- positive for clockwise rotation
462
+ :param center: center of rotation
463
+ """
464
+ angle = np.radians(angle)
465
+ c,s = np.cos(angle), np.sin(angle)
466
+ R = np.array([[c,-s],[s,c]])
467
+
468
+ if use_cache and self._cache is None:
469
+ self.set_cache()
470
+
471
+ if use_cache:
472
+ locxy = self._cache[:,:2] - np.array(center)
473
+ self.pts[:,:2] = np.dot(R,locxy.T).T + np.array(center)
474
+ else:
475
+ locxy = self.pts[:,:2] - np.array(center)
476
+ self.pts[:,:2] = np.dot(R,locxy.T).T + np.array(center)
477
+
478
+ def rotate_xy(self, x:float, y:float, use_cache:bool = True):
479
+ """ Rotate the vector around the rotation center and a xy point """
480
+
481
+ if self._rotation_center is None:
482
+ logging.error('No rotation center defined -- set it before rotating by this routine')
483
+ return self
484
+
485
+ angle = np.degrees(np.arctan2(-(y-self._rotation_center[1]), x-self._rotation_center[0]))
486
+
487
+ if self._rotation_step is not None:
488
+ angle = np.round(angle/self._rotation_step)*self._rotation_step
489
+
490
+ return self.rotate(-angle, center=self._rotation_center, use_cache=use_cache)
423
491
  class vectorproperties:
424
492
  """ Vector properties """
425
493
  used:bool
@@ -13,170 +13,226 @@ myappid = 'wolf_hece_uliege' # arbitrary string
13
13
  ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
14
14
 
15
15
  from ..PyTranslate import _
16
+ from ..matplotlib_fig import Matplotlib_Figure, PRESET_LAYOUTS
16
17
 
17
18
  import wx
18
19
  import numpy as np
19
20
  import matplotlib.pyplot as plt
20
21
  import matplotlib.image as mpimg
22
+ from matplotlib.axes import Axes
23
+ from matplotlib.figure import Figure
24
+ from matplotlib.backend_bases import KeyEvent, MouseEvent
25
+ from PIL import Image, ImageOps
21
26
 
22
- def main():
23
- """
24
- Main function of curve digitizer
27
+ import logging
25
28
 
26
- """
27
- plt.ion()
28
- ex = wx.App()
29
- ex.MainLoop()
30
- curves=[]
31
- # open the dialog
32
- file=wx.FileDialog(None,_("Select image to digitize"),
33
- wildcard="jpeg image (*.jpg)|*.jpg|png image (*.png)|*.png")
34
- if file.ShowModal() == wx.ID_CANCEL:
35
- return
36
- else:
37
- #récuparétaion du nom de fichier avec chemin d'accès
38
- filein =file.GetPath()
39
-
40
- # show the image
41
- img = mpimg.imread(filein)
42
- fig, ax = plt.subplots()
43
- ax.imshow(img)
44
- ax.axis('off') # clear x-axis and y-axis
45
-
46
- # get reference length in x direction
47
- xfactor = getReferenceLength(0)
48
-
49
- MsgBox = wx.MessageDialog(None,_('Do you want to use the same reference along Y?'),style=wx.YES_NO)
50
- result=MsgBox.ShowModal()
51
- if result == wx.ID_YES:
52
- yfactor=xfactor
53
- else:
54
- # get the reference length in y direction
55
- yfactor = getReferenceLength(1)
56
-
57
- print(xfactor)
58
- print(yfactor)
59
-
60
- origin = getOrigin()
61
-
62
- # digitize curves until stoped by the user
63
- reply = wx.ID_YES
64
- show=True
65
- while reply==wx.ID_YES:
66
- if show:
67
- wx.MessageBox(_("Please digitize the curve.\n" +
68
- "Left click: select point\n"+
69
- "Right click: undo\n"+
70
- "Middle click or Return: finish"),
71
- _("Digitize curve"))
72
- show=False
73
-
74
- # get the curve points
75
- x = plt.ginput(
76
- -1,
77
- timeout=0,
78
- show_clicks=True
79
- )
80
- x = np.asarray(x)
29
+ class Digitizer:
81
30
 
82
- ax.plot(x[:,0],x[:,1],'g','linewidth',1.5)
31
+ def __init__(self):
83
32
 
84
- # convert the curve points from pixels to coordinates
85
- x[:,0] = (x[:,0]-origin[0]) * xfactor
86
- x[:,1] = (x[:,1]-origin[1]) * yfactor
33
+ """
34
+ Main function of curve digitizer
35
+ """
87
36
 
88
- curves.append(x)
89
- print(x)
37
+ plt.ion()
90
38
 
91
- MsgBox = wx.MessageDialog(None,_("Digitize another curve?"),style=wx.YES_NO)
92
- reply=MsgBox.ShowModal()
39
+ # self.curves=[]
93
40
 
94
- # write the data to a file
95
- # first get the filename
96
- validFile = False
41
+ # open the dialog
42
+ file = wx.FileDialog(None,_("Select image to digitize"),
43
+ wildcard="gif image (*.gif)|*.gif|jpeg image (*.jpg)|*.jpg|png image (*.png)|*.png|All files (*.*)|*.*",)
97
44
 
98
- while not validFile:
99
- file=wx.FileDialog(None,_("Select file to save the data"), wildcard=_("Simple text files (.txt)|*.txt"))
100
45
  if file.ShowModal() == wx.ID_CANCEL:
101
- wx.MessageBox(_("Please select a filename to save the data"),_("Filename error"))
46
+ return
102
47
  else:
103
48
  #récuparétaion du nom de fichier avec chemin d'accès
104
- fileout =file.GetPath()
105
- validFile = True
106
-
107
- # write the data to file
108
- f=open(fileout,'w')
109
- i=0
110
- for loccurv in curves:
111
- i+=1
112
- f.write('line'+str(i)+'\n')
113
- for idx,xy in enumerate(loccurv):
114
- f.write('{:14.6f}\t{:14.6f}\n'.format(xy[0],xy[1]))
115
- f.close()
116
-
117
- # clear the figure
118
- plt.clf()
119
-
120
- def getReferenceLength(index):
121
- """
122
- Get the reference length in the requested direction
123
-
124
- USAGE: factor = getReferenceLength(index)
125
-
126
- :param index : 0 for x-direction or 1 for y-direction
127
-
128
- """
129
-
130
- # define a 'direction' string
131
- direction = 'x' if index == 0 else 'y'
132
-
133
- # get the reference length
134
- reply = wx.ID_NO
135
- while reply==wx.ID_NO:
136
- wx.MessageBox(_("Use the mouse to select the reference length\n") +
137
- _("Click the start and the end of the reference length"),_("Select reference length"))
138
- coord = plt.ginput(
139
- 2,
140
- timeout=0,
141
- show_clicks=True
142
- ) # capture only two points
143
- # ask for a valid length
144
- validLength = False
145
- while not validLength:
146
- dlg=wx.TextEntryDialog(None,_("Enter the reference length"))
147
- dlg.ShowModal()
148
- reflength=float(dlg.GetValue())
149
- dlg.Destroy()
150
-
151
- if isinstance(reflength, float):
152
- validLength = True
49
+ self.filein =file.GetPath()
50
+
51
+ # show the image
52
+ self.figure = Matplotlib_Figure(PRESET_LAYOUTS.DEFAULT_EQUAL)
53
+ self.figure.cur_ax.set_aspect('equal')
54
+ self.figure.fig_properties._axes[0]._equal_axis == 1
55
+
56
+ # win = self.figure._collaps_pane.GetPane()
57
+ # self._convert_xy = wx.Button(win, -1, 'Convert XY to world coordinates')
58
+ # self._convert_xy.Bind(wx.EVT_BUTTON, self.convert_xy)
59
+ # self.figure._sizer_xls.Add(self._convert_xy, 0, wx.EXPAND)
60
+ # self.figure.Layout()
61
+
62
+ self.figure.add_image(self.filein, origin='lower')
63
+ self.fig.tight_layout()
64
+
65
+ self.ref_x = []
66
+ self.ref_y = []
67
+
68
+ self.ref_x_length = 0
69
+ self.ref_y_length = 0
70
+
71
+ self.xy = []
72
+
73
+ # get reference length in x direction
74
+ wx.MessageBox(_("Use SHIFT + Right Mouse Button to select two points as X reference.\n\nWe will use only the delta X to calculate the scaling factor.\nSo, the Y distance will be ignored."),_("Select reference X"))
75
+ self.new_line(is_world=False, label = 'Reference X', color='black', linewidth=2)
76
+ self.figure.action = ('Ref X', self._callback_pt)
77
+
78
+ @property
79
+ def ax(self) -> Axes:
80
+ return self.figure.ax[0]
81
+
82
+ @property
83
+ def fig(self) -> Figure:
84
+ return self.figure.fig
85
+
86
+ # def convert_xy(self, event):
87
+ # """
88
+ # Convert the pixel coordinates to world coordinates
89
+ # """
90
+ # xy = self.figure.get_xy_from_grid()
91
+
92
+ # xy[:,0] = (xy[:,0] - self.origin_img[0]) * self.factor_X + self.origin_world[0]
93
+ # xy[:,1] = (xy[:,1] - self.origin_img[1]) * self.factor_Y + self.origin_world[1]
94
+
95
+ # self.figure.fill_grid_with_xy_np(xy)
96
+
97
+ def new_line(self, is_world:bool = True, ax=None, **kwargs):
98
+
99
+ line_props = self.figure.new_line(ax=ax, **kwargs)
100
+
101
+ if is_world:
102
+ line_props.xscale = self.factor_X
103
+ line_props.yscale = self.factor_Y
104
+ line_props.xorigin_world = self.origin_world[0]
105
+ line_props.yorigin_world = self.origin_world[1]
106
+ line_props.xorigin_local = self.origin_img[0]
107
+ line_props.yorigin_local = self.origin_img[1]
108
+ line_props.populate()
109
+
110
+ def _callback_digitize(self, xy, which):
111
+
112
+ if which == 'Digitize':
113
+ pass
114
+ # self.xy.append(xy)
115
+ elif which == 'End Digitize':
116
+
117
+ MsgBox = wx.MessageDialog(None,_("Digitize another curve?"),style=wx.YES_NO)
118
+ reply=MsgBox.ShowModal()
119
+
120
+ if reply == wx.ID_YES:
121
+ self.new_line()
153
122
  else:
154
- wx.MessageBox(_("Please provide a valid length"),_("Error"))
123
+ self.figure.action = None
155
124
 
156
- # calculate scaling factor
157
- deltaref=coord[1][index]-coord[0][index]
158
- factor=reflength/deltaref
125
+ def _callback_origin(self, xy, which):
159
126
 
160
- reply = wx.MessageDialog(None,"{:4.0f} pixels in {:s} direction corresponding to {:4.4f} units. Is this correct?".format(deltaref, direction, reflength),style=wx.YES_NO)
127
+ if which == 'Origin':
128
+ self.origin_img = xy
161
129
 
162
- return factor
130
+ valid_origin = False
131
+ while not valid_origin:
132
+ dlg = wx.TextEntryDialog(None,_("Set the origin coordinate (X,Y)"),_("Set the origin"), "0,0")
133
+ ret = dlg.ShowModal()
163
134
 
164
- def getOrigin():
165
- """
166
- Get the Origin
135
+ if ret == wx.ID_OK:
136
+ origin = dlg.GetValue().split(',')
167
137
 
168
- """
169
- wx.MessageBox(_("Click one point"),_("Select an origin"))
170
- coord = plt.ginput(
171
- 1,
172
- timeout=0,
173
- show_clicks=True
174
- ) # capture only one points
138
+ try:
139
+ self.origin_world = (float(origin[0]),float(origin[1]))
140
+ valid_origin = True
141
+ except:
142
+ valid_origin = False
175
143
 
176
- msg=_('The origin is ')+ '(%d ; %d)' % (coord[0][0],coord[0][1])
177
- wx.MessageBox(msg)
178
- return (coord[0][0],coord[0][1])
144
+ wx.MessageBox(_("Please digitize the curve.\n\n" +
145
+ " - MAJ + Right click : add point\n"+
146
+ " - Press Enter : finish"),
147
+ _("Digitize curve"))
148
+
149
+ self.new_line(is_world = True, label = 'Curve', linewidth=1.5)
150
+ self.figure.action = ('Digitize', self._callback_digitize)
151
+
152
+ def _callback_pt(self, xy, which):
153
+
154
+ if which == 'Ref X':
155
+ self.ref_x.append(xy)
156
+
157
+ if len(self.ref_x) == 2:
158
+
159
+ validLength = False
160
+ dlg=wx.TextEntryDialog(None,_("Enter the reference length [user unit | mm | cm | m | km]"))
161
+
162
+ while not validLength:
163
+ dlg.ShowModal()
164
+
165
+ try:
166
+ self.ref_x_length = float(dlg.GetValue())
167
+ if self.ref_x_length > 0:
168
+ validLength = True
169
+ except:
170
+ validLength = False
171
+
172
+ dlg.Destroy()
173
+
174
+ # calculate scaling factor
175
+ deltaref = np.abs(self.ref_x[1][0] - self.ref_x[0][0])
176
+ self.factor_X = self.ref_x_length / deltaref
177
+
178
+ reply = wx.MessageDialog(None,"{:4.0f} pixels in {:s} direction corresponding to {:4.4f} units. Is this correct?".format(deltaref, 'X', self.ref_x_length),style=wx.YES_NO)
179
+
180
+ if reply.ShowModal() == wx.ID_NO:
181
+ logging.info(_('Retry !'))
182
+ self.ref_x = []
183
+ self.ref_x_length = 0
184
+ else:
185
+ self.figure.action = None
186
+ MsgBox = wx.MessageDialog(None,_('Do you want to use the same reference along Y?'),style=wx.YES_NO)
187
+ result=MsgBox.ShowModal()
188
+ if result == wx.ID_YES:
189
+ self.factor_Y = self.factor_X
190
+
191
+ wx.MessageBox(_("Click one point for a reference in local axis (s,z)"),_("Select an origin"))
192
+ self.new_line(is_world = False, label = 'Origin', color='red', linewidth=4)
193
+ self.figure.action = ('Origin', self._callback_origin)
194
+ else:
195
+ # get the reference length in y direction
196
+ self.new_line(is_world = False, label = 'Reference Y', color='black', linewidth=2)
197
+ wx.MessageBox(_("Use SHIFT + Right Mouse Button to select two points as Y reference.\n\nWe will use only the delta Y to calculate the scaling factor.\nSo, the X distance will be ignored."),_("Select reference Y"))
198
+ self.figure.action = ('Ref Y', self._callback_pt)
199
+
200
+ elif which == 'Ref Y':
201
+ self.ref_y.append(xy)
202
+
203
+ if len(self.ref_y) == 2:
204
+
205
+ validLength = False
206
+ dlg=wx.TextEntryDialog(None,_("Enter the reference length [user unit | mm | cm | m | km]"))
207
+ while not validLength:
208
+ dlg.ShowModal()
209
+
210
+ try:
211
+ self.ref_y_length = float(dlg.GetValue())
212
+ if self.ref_y_length > 0:
213
+ validLength = True
214
+ except:
215
+ validLength = False
216
+
217
+ dlg.Destroy()
218
+
219
+ # calculate scaling factor
220
+ deltaref = np.abs(self.ref_y[1][1] - self.ref_y[0][1])
221
+ self.factor_Y = self.ref_y_length / deltaref
222
+
223
+ reply = wx.MessageDialog(None,"{:4.0f} pixels in {:s} direction corresponding to {:4.4f} units. Is this correct?".format(deltaref, 'Y', self.ref_y_length),style=wx.YES_NO)
224
+
225
+ if reply.ShowModal() == wx.ID_NO:
226
+ logging.info(_('Retry !'))
227
+ self.ref_y = []
228
+ self.ref_y_length = 0
229
+ else:
230
+ wx.MessageBox(_("Click one point for a reference in local axis (s,z)"),_("Select an origin"))
231
+ self.new_line(is_world = False, label = 'Origin', color='red', linewidth=4)
232
+ self.figure.action = ('Origin', self._callback_origin)
179
233
 
180
234
  if __name__ == "__main__":
181
235
  # run the main function
182
- main()
236
+ ex = wx.App()
237
+ digit = Digitizer()
238
+ ex.MainLoop()
wolfhece/apps/version.py CHANGED
@@ -5,7 +5,7 @@ class WolfVersion():
5
5
 
6
6
  self.major = 2
7
7
  self.minor = 1
8
- self.patch = 109
8
+ self.patch = 110
9
9
 
10
10
  def __str__(self):
11
11