pygeodesy 24.6.24__py2.py3-none-any.whl → 24.7.7__py2.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.
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/METADATA +2 -2
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/RECORD +23 -23
- pygeodesy/__init__.py +7 -1
- pygeodesy/__main__.py +6 -1
- pygeodesy/basics.py +8 -4
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +10 -3
- pygeodesy/errors.py +10 -1
- pygeodesy/geodesici.py +1111 -324
- pygeodesy/geodesicw.py +5 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/gx.py +19 -30
- pygeodesy/geodesicx/gxline.py +83 -72
- pygeodesy/geodsolve.py +36 -57
- pygeodesy/internals.py +40 -13
- pygeodesy/karney.py +63 -16
- pygeodesy/lazily.py +23 -21
- pygeodesy/ltpTuples.py +4 -4
- pygeodesy/rhumb/solve.py +21 -22
- pygeodesy/solveBase.py +177 -123
- pygeodesy/units.py +5 -5
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/top_level.txt +0 -0
pygeodesy/rhumb/solve.py
CHANGED
|
@@ -17,21 +17,21 @@ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv,
|
|
|
17
17
|
_PYGEODESY_RHUMBSOLVE_
|
|
18
18
|
from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
|
|
19
19
|
from pygeodesy.props import deprecated_method, Property, Property_RO
|
|
20
|
-
from pygeodesy.solveBase import
|
|
20
|
+
from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
|
|
21
21
|
from pygeodesy.utily import _unrollon, _Wrap, wrap360
|
|
22
22
|
|
|
23
23
|
__all__ = _ALL_LAZY.rhumb_solve
|
|
24
|
-
__version__ = '24.06.
|
|
24
|
+
__version__ = '24.06.28'
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
class _RhumbSolveBase(
|
|
27
|
+
class _RhumbSolveBase(_SolveGDictBase):
|
|
28
28
|
'''(INTERNAL) Base class for L{RhumbSolve} and L{RhumbLineSolve}.
|
|
29
29
|
'''
|
|
30
30
|
_Error = RhumbError
|
|
31
31
|
_Names_Direct = _lat2_, _lon2_, _S12_
|
|
32
32
|
_Names_Inverse = _azi12_, _s12_, _S12_
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
_Xable_name = 'RhumbSolve'
|
|
34
|
+
_Xable_path = _getenv(_PYGEODESY_RHUMBSOLVE_, _PYGEODESY_RHUMBSOLVE_)
|
|
35
35
|
|
|
36
36
|
@Property_RO
|
|
37
37
|
def _cmdBasic(self):
|
|
@@ -46,7 +46,7 @@ class _RhumbSolveBase(_SolveBase):
|
|
|
46
46
|
'''Get the U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
47
47
|
executable (C{filename}).
|
|
48
48
|
'''
|
|
49
|
-
return self.
|
|
49
|
+
return self._Xable_path
|
|
50
50
|
|
|
51
51
|
@RhumbSolve.setter # PYCHOK setter!
|
|
52
52
|
def RhumbSolve(self, path):
|
|
@@ -56,7 +56,7 @@ class _RhumbSolveBase(_SolveBase):
|
|
|
56
56
|
@raise RhumbError: Invalid B{C{path}}, B{C{path}} doesn't exist or isn't
|
|
57
57
|
the C{RhumbSolve} executable.
|
|
58
58
|
'''
|
|
59
|
-
self.
|
|
59
|
+
self._setXable(path)
|
|
60
60
|
|
|
61
61
|
@Property_RO
|
|
62
62
|
def _s_option(self): # == not -E for GeodSolve
|
|
@@ -65,11 +65,11 @@ class _RhumbSolveBase(_SolveBase):
|
|
|
65
65
|
def toStr(self, **prec_sep): # PYCHOK signature
|
|
66
66
|
'''Return this C{RhumbSolve} as string.
|
|
67
67
|
|
|
68
|
-
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=
|
|
68
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
|
|
69
69
|
for the C{float} C{prec}ision, number of decimal digits
|
|
70
70
|
(0..9) and the C{sep}arator string to join. Trailing
|
|
71
|
-
zero decimals are stripped for B{C{prec}} values of
|
|
72
|
-
|
|
71
|
+
zero decimals are stripped for B{C{prec}} values of 1
|
|
72
|
+
and above, but kept for negative B{C{prec}} values.
|
|
73
73
|
|
|
74
74
|
@return: RhumbSolve items (C{str}).
|
|
75
75
|
'''
|
|
@@ -173,8 +173,7 @@ class RhumbSolve(_RhumbSolveBase):
|
|
|
173
173
|
return r
|
|
174
174
|
|
|
175
175
|
def _GDictInverse(self, lat1, lon1, lat2, lon2, *unused, **floats): # PYCHOK signature
|
|
176
|
-
'''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but
|
|
177
|
-
I{without} C{_SALPs_CALPs_}.
|
|
176
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but I{without} C{_S_CALPs_}.
|
|
178
177
|
'''
|
|
179
178
|
i = _RhumbSolveBase._GDictInverse(self, lat1, lon1, lat2, lon2, **floats)
|
|
180
179
|
a = _over(float(i.s12), self._mpd) # for .Inverse1
|
|
@@ -231,7 +230,7 @@ class RhumbSolve(_RhumbSolveBase):
|
|
|
231
230
|
Line = DirectLine
|
|
232
231
|
|
|
233
232
|
|
|
234
|
-
class RhumbLineSolve(_RhumbSolveBase,
|
|
233
|
+
class RhumbLineSolve(_RhumbSolveBase, _SolveGDictLineBase):
|
|
235
234
|
'''Wrapper to invoke I{Karney}'s U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
236
235
|
like a class, similar to L{pygeodesy.RhumbLine} and L{pygeodesy.RhumbLineAux}.
|
|
237
236
|
|
|
@@ -267,7 +266,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
|
|
|
267
266
|
_xinstanceof(RhumbSolve, rhumb=rhumb)
|
|
268
267
|
if (caps & Caps.LINE_OFF): # copy to avoid updates
|
|
269
268
|
rhumb = rhumb.copy(deep=False, name=NN(_UNDER_, rhumb.name))
|
|
270
|
-
|
|
269
|
+
_SolveGDictLineBase.__init__(self, rhumb, lat1, lon1, caps, azi12=azi12, **name)
|
|
271
270
|
try:
|
|
272
271
|
self.RhumbSolve = rhumb.RhumbSolve # rhumb or copy of rhumb
|
|
273
272
|
except RhumbError:
|
|
@@ -283,7 +282,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
|
|
|
283
282
|
# azi12, a12, s12, S12}.
|
|
284
283
|
# '''
|
|
285
284
|
# s = a12 * self._mpd
|
|
286
|
-
# a = self._GDictInvoke(self._cmdArc,
|
|
285
|
+
# a = self._GDictInvoke(self._cmdArc, self._Names_Direct, s)
|
|
287
286
|
# r = GDict(a12=a12, s12=s, **self._lla1)
|
|
288
287
|
# r.updated(a)
|
|
289
288
|
# return r
|
|
@@ -318,7 +317,7 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
|
|
|
318
317
|
@return: A L{GDict} with 7 items C{lat1, lon1, lat2, lon2,
|
|
319
318
|
azi12, s12, S12}.
|
|
320
319
|
'''
|
|
321
|
-
d = self._GDictInvoke(self._cmdDistance,
|
|
320
|
+
d = self._GDictInvoke(self._cmdDistance, self._Names_Direct, s12)
|
|
322
321
|
r = GDict(s12=s12, **self._lla1) # a12=_over(s12, self._mpd)
|
|
323
322
|
r.update(d)
|
|
324
323
|
return r
|
|
@@ -326,16 +325,16 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
|
|
|
326
325
|
def toStr(self, **prec_sep): # PYCHOK signature
|
|
327
326
|
'''Return this C{RhumbLineSolve} as string.
|
|
328
327
|
|
|
329
|
-
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=
|
|
328
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
|
|
330
329
|
for the C{float} C{prec}ision, number of decimal digits
|
|
331
330
|
(0..9) and the C{sep}arator string to join. Trailing
|
|
332
|
-
zero decimals are stripped for B{C{prec}} values of
|
|
333
|
-
|
|
331
|
+
zero decimals are stripped for B{C{prec}} values of 1
|
|
332
|
+
and above, but kept for negative B{C{prec}} values.
|
|
334
333
|
|
|
335
334
|
@return: RhumbLineSolve items (C{str}).
|
|
336
335
|
'''
|
|
337
|
-
return
|
|
338
|
-
|
|
336
|
+
return _SolveGDictLineBase._toStr(self, azi12=self.azi12, rhumb=self._solve,
|
|
337
|
+
RhumbSolve=self.RhumbSolve, **prec_sep)
|
|
339
338
|
|
|
340
339
|
|
|
341
340
|
class RhumbSolve7Tuple(Rhumb8Tuple):
|
|
@@ -396,7 +395,7 @@ if __name__ == '__main__':
|
|
|
396
395
|
rS.verbose = '--verbose' in argv # or '-v' in argv
|
|
397
396
|
|
|
398
397
|
if rS.RhumbSolve in (_PYGEODESY_RHUMBSOLVE_, None): # not set
|
|
399
|
-
rS.RhumbSolve = '/opt/local/bin/RhumbSolve' # '/opt/local/Cellar/geographiclib/2.
|
|
398
|
+
rS.RhumbSolve = '/opt/local/bin/RhumbSolve' # '/opt/local/Cellar/geographiclib/2.3/bin/RhumbSolve' # HomeBrew
|
|
400
399
|
printf('version: %s', rS.version)
|
|
401
400
|
|
|
402
401
|
if len(argv) > 6: # 60 0 30 0 45 1e6
|
pygeodesy/solveBase.py
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
u'''(INTERNAL) Private base classes for L{pygeodesy.geodsolve} and L{pygeodesy.rhumb.solve}.
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
|
-
from pygeodesy.basics import map2, ub2str, _zip
|
|
7
|
+
from pygeodesy.basics import clips, map2, ub2str, _zip
|
|
8
8
|
from pygeodesy.constants import DIG
|
|
9
9
|
from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
10
10
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
11
|
-
from pygeodesy.errors import _AssertionError, _xkwds_get1,
|
|
11
|
+
from pygeodesy.errors import _AssertionError, _xkwds_get, _xkwds_get1, \
|
|
12
|
+
_xkwds_item2
|
|
12
13
|
from pygeodesy.internals import _enquote, printf
|
|
13
14
|
from pygeodesy.interns import NN, _0_, _BACKSLASH_, _COMMASPACE_, \
|
|
14
15
|
_EQUAL_, _Error_, _SPACE_, _UNUSED_
|
|
@@ -23,7 +24,7 @@ from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
|
|
|
23
24
|
from subprocess import PIPE as _PIPE, Popen as _Popen, STDOUT as _STDOUT
|
|
24
25
|
|
|
25
26
|
__all__ = _ALL_LAZY.solveBase
|
|
26
|
-
__version__ = '24.
|
|
27
|
+
__version__ = '24.07.08'
|
|
27
28
|
|
|
28
29
|
_ERROR_ = 'ERROR'
|
|
29
30
|
_Popen_kwds = dict(creationflags=0,
|
|
@@ -43,36 +44,95 @@ def _cmd_stdin_(cmd, stdin): # PYCHOK no cover
|
|
|
43
44
|
return _SPACE_.join(cmd)
|
|
44
45
|
|
|
45
46
|
|
|
47
|
+
# def _float_int(r):
|
|
48
|
+
# '''(INTERNAL) Convert result into C{float} or C{int}.
|
|
49
|
+
# '''
|
|
50
|
+
# f = float(r)
|
|
51
|
+
# i = int(f)
|
|
52
|
+
# return i if float(i) == f else f # PYCHOK inconsistent
|
|
53
|
+
|
|
54
|
+
|
|
46
55
|
def _popen2(cmd, stdin=None): # in .mgrs, test.bases, .testMgrs
|
|
47
56
|
'''(INTERNAL) Invoke C{B{cmd} tuple} and return C{exitcode}
|
|
48
|
-
and all output
|
|
57
|
+
and all output from C{stdout/-err}.
|
|
49
58
|
'''
|
|
50
59
|
p = _Popen(cmd, **_Popen_kwds) # PYCHOK kwArgs
|
|
51
|
-
r = p.communicate(stdin)[0]
|
|
60
|
+
r = p.communicate(stdin)[0] # stdout + NL + stderr
|
|
52
61
|
return p.returncode, ub2str(r).strip()
|
|
53
62
|
|
|
54
63
|
|
|
55
64
|
class _SolveCapsBase(_CapsBase):
|
|
56
65
|
'''(NTERNAL) Base class for C{_SolveBase} and C{_LineSolveBase}.
|
|
57
66
|
'''
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
_prec
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
_status
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
_datum = _WGS84
|
|
68
|
+
_Error = None
|
|
69
|
+
_Exact = True
|
|
70
|
+
_invokation = 0
|
|
71
|
+
_linelimit = 0
|
|
72
|
+
_prec = Precision_(prec=DIG)
|
|
73
|
+
_prec2stdin = DIG
|
|
74
|
+
_Xable_name = NN # executable basename
|
|
75
|
+
_Xable_path = NN # executable path
|
|
76
|
+
_status = None
|
|
77
|
+
_verbose = False
|
|
78
|
+
|
|
79
|
+
@Property_RO
|
|
80
|
+
def a(self):
|
|
81
|
+
'''Get the I{equatorial} radius, semi-axis (C{meter}).
|
|
82
|
+
'''
|
|
83
|
+
return self.ellipsoid.a
|
|
70
84
|
|
|
71
85
|
@property_RO
|
|
72
86
|
def _cmdBasic(self): # PYCHOK no cover
|
|
73
87
|
'''(INTERNAL) I{Must be overloaded}.'''
|
|
74
88
|
notOverloaded(self, underOK=True)
|
|
75
89
|
|
|
90
|
+
@property_RO
|
|
91
|
+
def datum(self):
|
|
92
|
+
'''Get the datum (C{Datum}).
|
|
93
|
+
'''
|
|
94
|
+
return self._datum
|
|
95
|
+
|
|
96
|
+
def _Dict(self, Dict, n, v, floats=True, **unused):
|
|
97
|
+
if self.verbose: # PYCHOK no cover
|
|
98
|
+
self._print(_COMMASPACE_.join(map(Fmt.EQUAL, n, map(fstrzs, v))))
|
|
99
|
+
if floats:
|
|
100
|
+
v = map(float, v) # _float_int, see Intersectool._XDistInvoke
|
|
101
|
+
return Dict(_zip(n, v)) # strict=True
|
|
102
|
+
|
|
103
|
+
def _DictInvoke2(self, cmd, Names, Dict, args, **floats_R):
|
|
104
|
+
'''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
|
|
105
|
+
'''
|
|
106
|
+
N = len(Names)
|
|
107
|
+
if N < 1:
|
|
108
|
+
raise _AssertionError(cmd=cmd, Names=Names)
|
|
109
|
+
i = fstr(args, prec=self._prec2stdin, fmt=Fmt.F, sep=_SPACE_) if args else None # NOT Fmt.G!
|
|
110
|
+
t = self._invoke(cmd, stdin=i, **floats_R).lstrip().split() # 12-/++ tuple
|
|
111
|
+
if _xkwds_get(floats_R, _R=None): # == '-R' in cmd
|
|
112
|
+
return self._Dicts(Dict, Names, t, **floats_R), True
|
|
113
|
+
elif len(t) > N: # PYCHOK no cover
|
|
114
|
+
# unzip instrumented name=value pairs to names and values
|
|
115
|
+
n, v = _zip(*(p.split(_EQUAL_) for p in t[:-N])) # strict=True
|
|
116
|
+
v += tuple(t[-N:])
|
|
117
|
+
n += Names
|
|
118
|
+
else:
|
|
119
|
+
n, v = Names, t
|
|
120
|
+
r = self._Dict(Dict, n, t, **floats_R)
|
|
121
|
+
return self._iter2tion(r, **r), None
|
|
122
|
+
|
|
123
|
+
def _Dicts(self, Dict, Names, t, **floats_R):
|
|
124
|
+
i, N = 0, len(Names)
|
|
125
|
+
for x in range(0, len(t), N):
|
|
126
|
+
if t[x] == 'nan':
|
|
127
|
+
break
|
|
128
|
+
X = self._Dict(Dict, Names, t[x:x + N], **floats_R)
|
|
129
|
+
yield X.set_(iteration=i)
|
|
130
|
+
i += 1
|
|
131
|
+
|
|
132
|
+
@Property_RO
|
|
133
|
+
def _E_option(self):
|
|
134
|
+
return ('-E',) if self.Exact else ()
|
|
135
|
+
|
|
76
136
|
@property
|
|
77
137
|
def Exact(self):
|
|
78
138
|
'''Get the Solve's C{exact} setting (C{bool}).
|
|
@@ -89,27 +149,28 @@ class _SolveCapsBase(_CapsBase):
|
|
|
89
149
|
_update_all(self)
|
|
90
150
|
self._Exact = Exact
|
|
91
151
|
|
|
92
|
-
|
|
93
|
-
|
|
152
|
+
@Property_RO
|
|
153
|
+
def ellipsoid(self):
|
|
154
|
+
'''Get the ellipsoid (C{Ellipsoid}).
|
|
94
155
|
'''
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if
|
|
101
|
-
#
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
156
|
+
return self.datum.ellipsoid
|
|
157
|
+
|
|
158
|
+
@Property_RO
|
|
159
|
+
def _e_option(self):
|
|
160
|
+
E = self.ellipsoid
|
|
161
|
+
if E is _EWGS84:
|
|
162
|
+
return () # default
|
|
163
|
+
a, f = strs(E.a_f, fmt=Fmt.F, prec=DIG + 3) # not .G!
|
|
164
|
+
return ('-e', a, f)
|
|
165
|
+
|
|
166
|
+
@Property_RO
|
|
167
|
+
def flattening(self):
|
|
168
|
+
'''Get the C{ellipsoid}'s I{flattening} (C{scalar}), M{(a - b) / a},
|
|
169
|
+
C{0} for spherical, negative for prolate.
|
|
170
|
+
'''
|
|
171
|
+
return self.ellipsoid.f
|
|
172
|
+
|
|
173
|
+
f = flattening
|
|
113
174
|
|
|
114
175
|
@property_RO
|
|
115
176
|
def invokation(self):
|
|
@@ -134,7 +195,7 @@ class _SolveCapsBase(_CapsBase):
|
|
|
134
195
|
|
|
135
196
|
@note: The C{Solve} return code is in property L{status}.
|
|
136
197
|
'''
|
|
137
|
-
c = (self.
|
|
198
|
+
c = (self._Xable_path,) + map2(str, options) # map2(_enquote, options)
|
|
138
199
|
i = _xkwds_get1(stdin, stdin=None)
|
|
139
200
|
r = self._invoke(c, stdin=i)
|
|
140
201
|
s = self.status
|
|
@@ -145,7 +206,7 @@ class _SolveCapsBase(_CapsBase):
|
|
|
145
206
|
self._print(r)
|
|
146
207
|
return r
|
|
147
208
|
|
|
148
|
-
def _invoke(self, cmd, stdin=None):
|
|
209
|
+
def _invoke(self, cmd, stdin=None, **unused): # _R=None
|
|
149
210
|
'''(INTERNAL) Invoke the C{Solve} executable, with the
|
|
150
211
|
given B{C{cmd}} line and optional input to B{C{stdin}}.
|
|
151
212
|
'''
|
|
@@ -161,8 +222,24 @@ class _SolveCapsBase(_CapsBase):
|
|
|
161
222
|
except (IOError, OSError, TypeError, ValueError) as x:
|
|
162
223
|
raise self._Error(cmd=t or _cmd_stdin_(cmd, stdin), cause=x)
|
|
163
224
|
self._status = s
|
|
225
|
+
if self.verbose: # and _R is None: # PYCHOK no cover
|
|
226
|
+
self._print(repr(r))
|
|
164
227
|
return r
|
|
165
228
|
|
|
229
|
+
def linelimit(self, *limit):
|
|
230
|
+
'''Set and get the print line length limit.
|
|
231
|
+
|
|
232
|
+
@arg limit: New line limit (C{int}) or C{0}
|
|
233
|
+
or C{None} for unlimited.
|
|
234
|
+
|
|
235
|
+
@return: Teh previous limit (C{int}).
|
|
236
|
+
'''
|
|
237
|
+
n = self._linelimit
|
|
238
|
+
if limit:
|
|
239
|
+
m = int(limit[0] or 0)
|
|
240
|
+
self._linelimit = max(80, m) if m > 0 else (n if m < 0 else 0)
|
|
241
|
+
return n
|
|
242
|
+
|
|
166
243
|
@Property_RO
|
|
167
244
|
def _mpd(self): # meter per degree
|
|
168
245
|
return self.ellipsoid._Lpd
|
|
@@ -194,42 +271,29 @@ class _SolveCapsBase(_CapsBase):
|
|
|
194
271
|
def _print(self, line): # PYCHOK no cover
|
|
195
272
|
'''(INTERNAL) Print a status line.
|
|
196
273
|
'''
|
|
274
|
+
if self._linelimit:
|
|
275
|
+
line = clips(line, limit=self._linelimit, length=True)
|
|
197
276
|
if self.status is not None:
|
|
198
277
|
line = _SPACE_(line, Fmt.PAREN(self.status))
|
|
199
|
-
printf('%s
|
|
200
|
-
|
|
201
|
-
@Property
|
|
202
|
-
def reverse2(self):
|
|
203
|
-
'''Get the C{azi2} direction (C{bool}).
|
|
204
|
-
'''
|
|
205
|
-
return self._reverse2
|
|
278
|
+
printf('%s@%d: %s', self.named2, self.invokation, line)
|
|
206
279
|
|
|
207
|
-
|
|
208
|
-
def reverse2(self, reverse2):
|
|
209
|
-
'''Set the direction for C{azi2} (C{bool}), if C{True} reverse C{azi2}.
|
|
210
|
-
'''
|
|
211
|
-
reverse2 = bool(reverse2)
|
|
212
|
-
if self._reverse2 != reverse2:
|
|
213
|
-
_update_all(self)
|
|
214
|
-
self._reverse2 = reverse2
|
|
215
|
-
|
|
216
|
-
def _setSolve(self, path, **Solve_path):
|
|
280
|
+
def _setXable(self, path, **Xable_path):
|
|
217
281
|
'''(INTERNAL) Set the executable C{path}.
|
|
218
282
|
'''
|
|
219
|
-
hold = self.
|
|
283
|
+
hold = self._Xable_path
|
|
220
284
|
if hold != path:
|
|
221
285
|
_update_all(self)
|
|
222
|
-
self.
|
|
286
|
+
self._Xable_path = path
|
|
223
287
|
try:
|
|
224
288
|
_ = self.version # test path and ...
|
|
225
289
|
if self.status: # ... return code
|
|
226
|
-
S_p =
|
|
290
|
+
S_p = Xable_path or {self._Xable_name: _enquote(path)}
|
|
227
291
|
raise self._Error(status=self.status, txt_not_=_0_, **S_p)
|
|
228
292
|
hold = path
|
|
229
293
|
finally: # restore in case of error
|
|
230
|
-
if self.
|
|
294
|
+
if self._Xable_path != hold:
|
|
231
295
|
_update_all(self)
|
|
232
|
-
self.
|
|
296
|
+
self._Xable_path = hold
|
|
233
297
|
|
|
234
298
|
@property_RO
|
|
235
299
|
def status(self):
|
|
@@ -238,21 +302,6 @@ class _SolveCapsBase(_CapsBase):
|
|
|
238
302
|
'''
|
|
239
303
|
return self._status
|
|
240
304
|
|
|
241
|
-
@Property
|
|
242
|
-
def unroll(self):
|
|
243
|
-
'''Get the C{lon2} unroll'ing (C{bool}).
|
|
244
|
-
'''
|
|
245
|
-
return self._unroll
|
|
246
|
-
|
|
247
|
-
@unroll.setter # PYCHOK setter!
|
|
248
|
-
def unroll(self, unroll):
|
|
249
|
-
'''Set unroll'ing for C{lon2} (C{bool}), if C{True} unroll C{lon2}, otherwise don't.
|
|
250
|
-
'''
|
|
251
|
-
unroll = bool(unroll)
|
|
252
|
-
if self._unroll != unroll:
|
|
253
|
-
_update_all(self)
|
|
254
|
-
self._unroll = unroll
|
|
255
|
-
|
|
256
305
|
@property
|
|
257
306
|
def verbose(self):
|
|
258
307
|
'''Get the C{verbose} option (C{bool}).
|
|
@@ -274,9 +323,47 @@ class _SolveCapsBase(_CapsBase):
|
|
|
274
323
|
|
|
275
324
|
|
|
276
325
|
class _SolveBase(_SolveCapsBase):
|
|
326
|
+
'''(INTERNAL) Base class for C{_SolveBase} and C{_SolveLineBase}.
|
|
327
|
+
'''
|
|
328
|
+
_Names_Direct = \
|
|
329
|
+
_Names_Inverse = ()
|
|
330
|
+
_reverse2 = False
|
|
331
|
+
_unroll = False
|
|
332
|
+
|
|
333
|
+
@Property
|
|
334
|
+
def reverse2(self):
|
|
335
|
+
'''Get the C{azi2} direction (C{bool}).
|
|
336
|
+
'''
|
|
337
|
+
return self._reverse2
|
|
338
|
+
|
|
339
|
+
@reverse2.setter # PYCHOK setter!
|
|
340
|
+
def reverse2(self, reverse2):
|
|
341
|
+
'''Set the direction for C{azi2} (C{bool}), if C{True} reverse C{azi2}.
|
|
342
|
+
'''
|
|
343
|
+
reverse2 = bool(reverse2)
|
|
344
|
+
if self._reverse2 != reverse2:
|
|
345
|
+
_update_all(self)
|
|
346
|
+
self._reverse2 = reverse2
|
|
347
|
+
|
|
348
|
+
@Property
|
|
349
|
+
def unroll(self):
|
|
350
|
+
'''Get the C{lon2} unroll'ing (C{bool}).
|
|
351
|
+
'''
|
|
352
|
+
return self._unroll
|
|
353
|
+
|
|
354
|
+
@unroll.setter # PYCHOK setter!
|
|
355
|
+
def unroll(self, unroll):
|
|
356
|
+
'''Set unroll'ing for C{lon2} (C{bool}), if C{True} unroll C{lon2}, otherwise don't.
|
|
357
|
+
'''
|
|
358
|
+
unroll = bool(unroll)
|
|
359
|
+
if self._unroll != unroll:
|
|
360
|
+
_update_all(self)
|
|
361
|
+
self._unroll = unroll
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
class _SolveGDictBase(_SolveBase):
|
|
277
365
|
'''(NTERNAL) Base class for C{_GeodesicSolveBase} and C{_RhumbSolveBase}.
|
|
278
366
|
'''
|
|
279
|
-
_datum = _WGS84
|
|
280
367
|
|
|
281
368
|
def __init__(self, a_ellipsoid=_EWGS84, f=None, path=NN, **name):
|
|
282
369
|
'''New C{Solve} instance.
|
|
@@ -296,13 +383,7 @@ class _SolveBase(_SolveCapsBase):
|
|
|
296
383
|
if name:
|
|
297
384
|
self.name = name
|
|
298
385
|
if path:
|
|
299
|
-
self.
|
|
300
|
-
|
|
301
|
-
@Property_RO
|
|
302
|
-
def a(self):
|
|
303
|
-
'''Get the I{equatorial} radius, semi-axis (C{meter}).
|
|
304
|
-
'''
|
|
305
|
-
return self.ellipsoid.a
|
|
386
|
+
self._setXable(path)
|
|
306
387
|
|
|
307
388
|
@Property_RO
|
|
308
389
|
def _cmdDirect(self):
|
|
@@ -316,56 +397,29 @@ class _SolveBase(_SolveCapsBase):
|
|
|
316
397
|
'''
|
|
317
398
|
return self._cmdBasic + ('-i',)
|
|
318
399
|
|
|
319
|
-
@property_RO
|
|
320
|
-
def datum(self):
|
|
321
|
-
'''Get the datum (C{Datum}).
|
|
322
|
-
'''
|
|
323
|
-
return self._datum
|
|
324
|
-
|
|
325
400
|
def Direct(self, lat1, lon1, azi1, s12, outmask=_UNUSED_): # PYCHOK unused
|
|
326
401
|
'''Return the C{Direct} result.
|
|
327
402
|
'''
|
|
328
403
|
return self._GDictDirect(lat1, lon1, azi1, False, s12)
|
|
329
404
|
|
|
330
|
-
@Property_RO
|
|
331
|
-
def ellipsoid(self):
|
|
332
|
-
'''Get the ellipsoid (C{Ellipsoid}).
|
|
333
|
-
'''
|
|
334
|
-
return self.datum.ellipsoid
|
|
335
|
-
|
|
336
|
-
@Property_RO
|
|
337
|
-
def _e_option(self):
|
|
338
|
-
E = self.ellipsoid
|
|
339
|
-
if E is _EWGS84:
|
|
340
|
-
return () # default
|
|
341
|
-
a, f = strs(E.a_f, fmt=Fmt.F, prec=DIG + 3) # not .G!
|
|
342
|
-
return ('-e', a, f)
|
|
343
|
-
|
|
344
|
-
@Property_RO
|
|
345
|
-
def flattening(self):
|
|
346
|
-
'''Get the C{ellipsoid}'s I{flattening} (C{scalar}), M{(a - b) / a},
|
|
347
|
-
C{0} for spherical, negative for prolate.
|
|
348
|
-
'''
|
|
349
|
-
return self.ellipsoid.f
|
|
350
|
-
|
|
351
|
-
f = flattening
|
|
352
|
-
|
|
353
405
|
def _GDictDirect(self, lat, lon, azi, arcmode, s12_a12, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
|
|
354
406
|
'''(INTERNAL) Get C{_GenDirect}-like result as C{GDict}.
|
|
355
407
|
'''
|
|
356
408
|
if arcmode:
|
|
357
409
|
raise self._Error(arcmode=arcmode, txt=str(NotImplemented))
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
lat, lon, azi, s12_a12)
|
|
410
|
+
return self._GDictInvoke(self._cmdDirect, self._Names_Direct,
|
|
411
|
+
lat, lon, azi, s12_a12, **floats)
|
|
361
412
|
|
|
362
413
|
def _GDictInverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
|
|
363
|
-
'''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but
|
|
364
|
-
|
|
414
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but I{without} C{_S_CALPs_}.
|
|
415
|
+
'''
|
|
416
|
+
return self._GDictInvoke(self._cmdInverse, self._Names_Inverse,
|
|
417
|
+
lat1, lon1, lat2, lon2, **floats)
|
|
418
|
+
|
|
419
|
+
def _GDictInvoke(self, cmd, Names, *args, **floats):
|
|
420
|
+
'''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
|
|
365
421
|
'''
|
|
366
|
-
|
|
367
|
-
return self._GDictInvoke(self._cmdInverse, floats, self._Names_Inverse,
|
|
368
|
-
lat1, lon1, lat2, lon2)
|
|
422
|
+
return self._DictInvoke2(cmd, Names, GDict, args, **floats)[0] # _R
|
|
369
423
|
|
|
370
424
|
def Inverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_): # PYCHOK unused
|
|
371
425
|
'''Return the C{Inverse} result.
|
|
@@ -390,7 +444,7 @@ class _SolveBase(_SolveCapsBase):
|
|
|
390
444
|
return sep.join(pairs(d, prec=prec))
|
|
391
445
|
|
|
392
446
|
|
|
393
|
-
class
|
|
447
|
+
class _SolveGDictLineBase(_SolveGDictBase):
|
|
394
448
|
'''(NTERNAL) Base class for C{GeodesicLineSolve} and C{RhumbLineSolve}.
|
|
395
449
|
'''
|
|
396
450
|
# _caps = 0
|
|
@@ -451,7 +505,7 @@ class _SolveLineBase(_SolveCapsBase):
|
|
|
451
505
|
return sep.join(pairs(d, prec=prec))
|
|
452
506
|
|
|
453
507
|
|
|
454
|
-
__all__ += _ALL_DOCS(_SolveBase,
|
|
508
|
+
__all__ += _ALL_DOCS(_SolveBase, _SolveCapsBase, _SolveGDictBase, _SolveGDictLineBase)
|
|
455
509
|
|
|
456
510
|
# **) MIT License
|
|
457
511
|
#
|
pygeodesy/units.py
CHANGED
|
@@ -27,7 +27,7 @@ from pygeodesy.unitsBase import Float, Int, _NamedUnit, Radius, Str, Fmt, fstr
|
|
|
27
27
|
from math import degrees, radians
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.units
|
|
30
|
-
__version__ = '24.06.
|
|
30
|
+
__version__ = '24.06.29'
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class Float_(Float):
|
|
@@ -781,10 +781,10 @@ class Zone(Int):
|
|
|
781
781
|
return Int_.__new__(cls, arg=arg, name=name, **Error_name_arg)
|
|
782
782
|
|
|
783
783
|
|
|
784
|
-
|
|
785
|
-
_Degrees = (Bearing, Bearing_, Degrees, Degrees_) +
|
|
786
|
-
_Meters = (Distance, Distance_, Meter, Meter_) +
|
|
787
|
-
_Radians = (Radians, Radians_) +
|
|
784
|
+
_ScalarU = Float, Float_, Scalar, Scalar_
|
|
785
|
+
_Degrees = (Bearing, Bearing_, Degrees, Degrees_) + _ScalarU
|
|
786
|
+
_Meters = (Distance, Distance_, Meter, Meter_) + _ScalarU
|
|
787
|
+
_Radians = (Radians, Radians_) + _ScalarU # PYCHOK unused
|
|
788
788
|
_Radii = _Meters + (Radius, Radius_)
|
|
789
789
|
|
|
790
790
|
|
|
File without changes
|
|
File without changes
|