pygeodesy 24.6.24__py2.py3-none-any.whl → 24.7.24__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.24.dist-info}/METADATA +25 -23
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/RECORD +38 -38
- pygeodesy/__init__.py +52 -46
- pygeodesy/__main__.py +6 -1
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/basics.py +8 -4
- pygeodesy/cartesianBase.py +5 -6
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +10 -3
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/errors.py +10 -1
- pygeodesy/fsums.py +12 -6
- pygeodesy/geodesici.py +1218 -330
- pygeodesy/geodesicw.py +69 -42
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/gx.py +20 -31
- pygeodesy/geodesicx/gxline.py +84 -73
- pygeodesy/geodsolve.py +44 -56
- pygeodesy/geoids.py +8 -10
- pygeodesy/internals.py +40 -13
- pygeodesy/karney.py +127 -74
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +4 -5
- pygeodesy/lazily.py +25 -22
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +4 -4
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +21 -22
- pygeodesy/solveBase.py +196 -128
- pygeodesy/triaxials.py +4 -5
- pygeodesy/units.py +5 -5
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/top_level.txt +0 -0
pygeodesy/props.py
CHANGED
|
@@ -25,7 +25,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
|
25
25
|
from functools import wraps as _wraps
|
|
26
26
|
|
|
27
27
|
__all__ = _ALL_LAZY.props
|
|
28
|
-
__version__ = '24.
|
|
28
|
+
__version__ = '24.07.23'
|
|
29
29
|
|
|
30
30
|
_class_ = 'class'
|
|
31
31
|
_dont_use_ = _DEPRECATED_ + ", don't use."
|
|
@@ -48,11 +48,12 @@ def _allPropertiesOf(Clas_or_inst, *Bases, **excls):
|
|
|
48
48
|
except AttributeError:
|
|
49
49
|
raise
|
|
50
50
|
S = () # not an inst
|
|
51
|
-
B
|
|
52
|
-
|
|
51
|
+
B = Bases or _PropertyBase
|
|
52
|
+
P = _property_RO___
|
|
53
53
|
for C in S:
|
|
54
54
|
for n, p in C.__dict__.items():
|
|
55
|
-
if
|
|
55
|
+
if isinstance(p, B) and p.name == n and not (
|
|
56
|
+
isinstance(p, P) or n in excls):
|
|
56
57
|
yield p
|
|
57
58
|
|
|
58
59
|
|
|
@@ -251,9 +252,9 @@ class Property_RO(_PropertyBase):
|
|
|
251
252
|
<https://Docs.Python.org/3/library/functools.html#functools.cache>}
|
|
252
253
|
to I{cache} or I{memoize} the property value.
|
|
253
254
|
|
|
254
|
-
@see: Luciano Ramalho, "Fluent Python", O'Reilly,
|
|
255
|
-
|
|
256
|
-
<https://docs.Python.org/3/howto/descriptor.html>}.
|
|
255
|
+
@see: Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 636
|
|
256
|
+
Example 19-24 or 2022 p. 870 Example 22-28 and U{class
|
|
257
|
+
Property<https://docs.Python.org/3/howto/descriptor.html>}.
|
|
257
258
|
'''
|
|
258
259
|
_fget = method if _FOR_DOCS else self._fget # XXX force method.__doc__ to epydoc
|
|
259
260
|
_PropertyBase.__init__(self, method, _fget, self._fset_error)
|
|
@@ -355,6 +356,61 @@ class property_RO(_PropertyBase):
|
|
|
355
356
|
inst.__dict__.pop(uname)
|
|
356
357
|
|
|
357
358
|
|
|
359
|
+
class _property_RO___(_PropertyBase):
|
|
360
|
+
# No __doc__ on purpose
|
|
361
|
+
|
|
362
|
+
def __init__(self, method, doc=NN): # PYCHOK expected
|
|
363
|
+
'''New C{property_ROnce} or C{property_ROver}, holding a singleton value as
|
|
364
|
+
class attribute for all instances of that class and overwriting C{self},
|
|
365
|
+
the C{property_ROver} instance in the 1st invokation.
|
|
366
|
+
|
|
367
|
+
@see: L{property_RO} for further details.
|
|
368
|
+
'''
|
|
369
|
+
_PropertyBase.__init__(self, method, self._fget, self._fset_error, doc=doc)
|
|
370
|
+
|
|
371
|
+
def _fdel(self, unused): # PYCHOK no cover
|
|
372
|
+
'''Silently ignored, always.
|
|
373
|
+
'''
|
|
374
|
+
pass
|
|
375
|
+
|
|
376
|
+
def _update(self, *unused): # PYCHOK signature
|
|
377
|
+
'''(INTERNAL) No-op, ignore updates.
|
|
378
|
+
'''
|
|
379
|
+
pass
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
class property_ROnce(_property_RO___):
|
|
383
|
+
# No __doc__ on purpose
|
|
384
|
+
|
|
385
|
+
def _fget(self, inst):
|
|
386
|
+
'''Get the C{property} value, only I{once} and memoize/cache it.
|
|
387
|
+
'''
|
|
388
|
+
try:
|
|
389
|
+
v = self._val
|
|
390
|
+
except AttributeError:
|
|
391
|
+
v = self._val = self.method(inst)
|
|
392
|
+
return v
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class property_ROver(_property_RO___):
|
|
396
|
+
# No __doc__ on purpose
|
|
397
|
+
|
|
398
|
+
def _fget(self, inst):
|
|
399
|
+
'''Get the C{property} value I{once} and overwrite C{self}, this C{property} instance.
|
|
400
|
+
'''
|
|
401
|
+
v = self.method(inst)
|
|
402
|
+
n = self.name
|
|
403
|
+
C = inst.__class__
|
|
404
|
+
for c in C.__mro__: # [:-1]
|
|
405
|
+
if getattr(c, n, None) is self:
|
|
406
|
+
setattr(c, n, v) # overwrite property_ROver
|
|
407
|
+
break
|
|
408
|
+
else:
|
|
409
|
+
n = _DOT_(C.__name__, n)
|
|
410
|
+
raise _AssertionError(_EQUALSPACED_(n, v))
|
|
411
|
+
return v
|
|
412
|
+
|
|
413
|
+
|
|
358
414
|
class _NamedProperty(property):
|
|
359
415
|
'''Class C{property} with retrievable name.
|
|
360
416
|
'''
|
|
@@ -372,16 +428,18 @@ def property_doc_(doc):
|
|
|
372
428
|
|
|
373
429
|
@example:
|
|
374
430
|
|
|
375
|
-
>>>
|
|
376
|
-
>>>
|
|
377
|
-
>>>
|
|
431
|
+
>>>class Clas(object):
|
|
432
|
+
>>>
|
|
433
|
+
>>> @property_doc_("documentation text.")
|
|
434
|
+
>>> def name(self):
|
|
435
|
+
>>> ...
|
|
378
436
|
>>>
|
|
379
|
-
>>>
|
|
380
|
-
>>>
|
|
381
|
-
>>>
|
|
437
|
+
>>> @name.setter
|
|
438
|
+
>>> def name(self, value):
|
|
439
|
+
>>> ...
|
|
382
440
|
'''
|
|
383
|
-
# See Luciano Ramalho, "Fluent Python", O'Reilly,
|
|
384
|
-
#
|
|
441
|
+
# See Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 212+
|
|
442
|
+
# Example 7-23 or 2022 p. 331+ Example 9-22 and <https://
|
|
385
443
|
# Python-3-Patterns-Idioms-Test.ReadTheDocs.io/en/latest/PythonDecorators.html>
|
|
386
444
|
|
|
387
445
|
def _documented_property(method):
|
|
@@ -396,8 +454,8 @@ def property_doc_(doc):
|
|
|
396
454
|
def _deprecated(call, kind, qual_d):
|
|
397
455
|
'''(INTERNAL) Decorator for DEPRECATED functions, methods, etc.
|
|
398
456
|
|
|
399
|
-
@see: Brett Slatkin, "Effective Python", page 105, 2nd
|
|
400
|
-
Addison-Wesley
|
|
457
|
+
@see: Brett Slatkin, "Effective Python", 2019 page 105, 2nd
|
|
458
|
+
ed, Addison-Wesley.
|
|
401
459
|
'''
|
|
402
460
|
doc = _docof(call)
|
|
403
461
|
|
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.
|
|
24
|
+
__version__ = '24.07.11'
|
|
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{_SALP_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
|