pygeodesy 24.7.7__py2.py3-none-any.whl → 24.8.4__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.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/METADATA +28 -26
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/RECORD +39 -39
- pygeodesy/__init__.py +50 -51
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/cartesianBase.py +6 -7
- pygeodesy/css.py +5 -5
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +12 -6
- pygeodesy/gars.py +59 -52
- pygeodesy/geodesici.py +232 -137
- pygeodesy/geodesicw.py +70 -45
- pygeodesy/geodesicx/gx.py +8 -8
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +12 -3
- pygeodesy/geohash.py +484 -267
- pygeodesy/geoids.py +13 -11
- pygeodesy/heights.py +30 -40
- pygeodesy/internals.py +19 -6
- pygeodesy/karney.py +85 -79
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +5 -6
- pygeodesy/lazily.py +21 -19
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +6 -6
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +26 -12
- pygeodesy/triaxials.py +6 -7
- pygeodesy/units.py +34 -17
- pygeodesy/wgrs.py +93 -83
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/top_level.txt +0 -0
pygeodesy/lazily.py
CHANGED
|
@@ -31,8 +31,7 @@ from pygeodesy import internals as _internals, interns as _interns, \
|
|
|
31
31
|
_isfrozen # DON'T _lazy_import2
|
|
32
32
|
# from pygeodesy.errors import _error_init, _xkwds_item2 # _ALL_MODS
|
|
33
33
|
from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_ismain, \
|
|
34
|
-
_headof,
|
|
35
|
-
_tailof # _Property_RO
|
|
34
|
+
_headof, printf, _Pythonarchine, _tailof # _Property_RO
|
|
36
35
|
from pygeodesy.interns import NN, _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, \
|
|
37
36
|
_doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
|
|
38
37
|
_HASH_, _immutable_, _line_, _module_, _no_, _not_, \
|
|
@@ -284,13 +283,13 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
284
283
|
fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
|
|
285
284
|
'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
|
|
286
285
|
gars=_i('Garef', 'GARSError'),
|
|
287
|
-
geodesici=_i('Intersectool', 'Intersectool5Tuple', '
|
|
288
|
-
'Intersector', 'Intersector5Tuple', 'XDict'),
|
|
286
|
+
geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Intersect7Tuple',
|
|
287
|
+
'Intersector', 'Intersector5Tuple', 'Middle5Tuple', 'XDict'),
|
|
289
288
|
geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
|
|
290
289
|
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
291
290
|
'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
|
|
292
291
|
geodsolve=_i('GeodesicSolve', 'GeodesicLineSolve', 'GeodSolve12Tuple'),
|
|
293
|
-
geohash=_i('Geohash', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple'),
|
|
292
|
+
geohash=_i('Geohash', 'Geohashed', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple', 'Sizes3Tuple'),
|
|
294
293
|
geoids=_i('GeoidError', 'GeoidG2012B', 'GeoidKarney', 'GeoidPGM', 'egmGeoidHeights',
|
|
295
294
|
'PGMError', 'GeoidHeight5Tuple'),
|
|
296
295
|
hausdorff=_i('Hausdorff', 'HausdorffDegrees', 'HausdorffError', 'HausdorffRadians',
|
|
@@ -343,7 +342,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
343
342
|
'areaOf', 'boundsOf', 'centroidOf', 'fractional',
|
|
344
343
|
'isclockwise', 'isconvex', 'isconvex_', 'isenclosedBy', 'ispolar',
|
|
345
344
|
'luneOf', 'nearestOn5', 'perimeterOf', 'quadOf'),
|
|
346
|
-
props=_i('Property', 'Property_RO', '
|
|
345
|
+
props=_i('Property', 'Property_RO', 'property_doc_',
|
|
346
|
+
'property_RO', 'property_ROnce', 'property_ROver',
|
|
347
347
|
'deprecated_class', 'deprecated_function', 'deprecated_method',
|
|
348
348
|
'deprecated_Property_RO', 'deprecated_property_RO', 'DeprecationWarnings'),
|
|
349
349
|
resections=_i('Collins5Tuple', 'ResectionError', 'Survey3Tuple', 'Tienstra7Tuple',
|
|
@@ -367,7 +367,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
367
367
|
triaxials=_i('BetaOmega2Tuple', 'BetaOmega3Tuple', 'Jacobi2Tuple',
|
|
368
368
|
'JacobiConformal', 'JacobiConformalSpherical',
|
|
369
369
|
'Triaxial', 'Triaxial_', 'TriaxialError', 'Triaxials', 'hartzell4'),
|
|
370
|
-
units=_i('Band', 'Bearing', 'Bearing_', 'Bool',
|
|
370
|
+
units=_i('Azimuth', 'Band', 'Bearing', 'Bearing_', 'Bool',
|
|
371
371
|
'Degrees', 'Degrees_', 'Degrees2', 'Distance', 'Distance_', 'Easting', 'Epoch',
|
|
372
372
|
'Feet', 'FIx', 'Float_', 'Height', 'Height_', 'HeightX', 'Int_',
|
|
373
373
|
'Lam', 'Lamd', 'Lat', 'Lat_', 'Lon', 'Lon_',
|
|
@@ -521,7 +521,7 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
521
521
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
522
522
|
|
|
523
523
|
__all__ = _ALL_LAZY.lazily
|
|
524
|
-
__version__ = '24.
|
|
524
|
+
__version__ = '24.08.01'
|
|
525
525
|
|
|
526
526
|
|
|
527
527
|
def _ALL_OTHER(*objs):
|
|
@@ -861,13 +861,13 @@ def _lazy_module(name): # overwritten by _lazy_import2
|
|
|
861
861
|
#
|
|
862
862
|
# return _ALL_OTHER(*sm.values())
|
|
863
863
|
|
|
864
|
-
|
|
865
864
|
# del _i, _i0
|
|
866
865
|
|
|
867
866
|
# _ = _ALL_MODS.errors # force import pygeodesy.errors
|
|
868
867
|
|
|
869
868
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
870
869
|
|
|
870
|
+
from pygeodesy.internals import _versions
|
|
871
871
|
from timeit import timeit
|
|
872
872
|
|
|
873
873
|
def t1():
|
|
@@ -881,22 +881,24 @@ if _dunder_ismain(__name__): # PYCHOK no cover
|
|
|
881
881
|
|
|
882
882
|
t1 = timeit(t1, number=1000000)
|
|
883
883
|
t2 = timeit(t2, number=1000000)
|
|
884
|
-
|
|
885
|
-
printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, v)
|
|
884
|
+
printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, _versions())
|
|
886
885
|
|
|
887
886
|
# del t1, t2, timeit, v
|
|
888
887
|
|
|
889
|
-
# python3.
|
|
890
|
-
# 0.
|
|
888
|
+
# % python3.13 -W ignore -m pygeodesy.lazily
|
|
889
|
+
# 0.102670 import vs 0.076113 _ALL_MODS: 1.35X, pygeodesy 24.8.4 Python 3.13.0b4 64bit arm64 macOS 14.5
|
|
890
|
+
|
|
891
|
+
# % python3.12 -W ignore -m pygeodesy.lazily
|
|
892
|
+
# 0.132801 import vs 0.079125 _ALL_MODS: 1.68X, pygeodesy 24.8.4 Python 3.12.4 64bit arm64 macOS 14.5
|
|
891
893
|
|
|
892
|
-
# python3.11 -W ignore -m pygeodesy.lazily
|
|
893
|
-
# 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, Python 3.11.5 64bit arm64 macOS 14.4.1
|
|
894
|
+
# % python3.11 -W ignore -m pygeodesy.lazily
|
|
895
|
+
# 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, pygeodesy 24.8.4 Python 3.11.5 64bit arm64 macOS 14.4.1
|
|
894
896
|
|
|
895
|
-
# python3.
|
|
896
|
-
# 0.
|
|
897
|
+
# % python3.8 -W ignore -m pygeodesy.lazily
|
|
898
|
+
# 0.570353 import vs 0.382842 _ALL_MODS: 1.49X, pygeodesy 24.8.4 Python 3.8.10 64bit arm64_x86_64 macOS 10.16
|
|
897
899
|
|
|
898
|
-
# python2 -m pygeodesy.lazily
|
|
899
|
-
# 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, Python 2.7.18 64bit arm64_x86_64 macOS 10.16
|
|
900
|
+
# % python2 -m pygeodesy.lazily
|
|
901
|
+
# 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, pygeodesy 24.8.4 Python 2.7.18 64bit arm64_x86_64 macOS 10.16
|
|
900
902
|
|
|
901
903
|
# **) MIT License
|
|
902
904
|
#
|
pygeodesy/ltp.py
CHANGED
|
@@ -33,8 +33,8 @@ from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
|
|
|
33
33
|
ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
|
|
34
34
|
from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
|
|
35
35
|
from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
|
|
36
|
-
from pygeodesy.props import Property, Property_RO, property_doc_,
|
|
37
|
-
|
|
36
|
+
from pygeodesy.props import Property, Property_RO, property_doc_, \
|
|
37
|
+
property_ROver, _update_all
|
|
38
38
|
from pygeodesy.streprs import Fmt, strs, unstr
|
|
39
39
|
from pygeodesy.units import Bearing, Degrees, _isHeight, Meter
|
|
40
40
|
from pygeodesy.utily import cotd, _loneg, sincos2d, sincos2d_, tand, tand_, \
|
|
@@ -44,7 +44,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
|
|
|
44
44
|
# from math import fabs, floor as _floor # from .fmath, .fsums
|
|
45
45
|
|
|
46
46
|
__all__ = _ALL_LAZY.ltp
|
|
47
|
-
__version__ = '24.
|
|
47
|
+
__version__ = '24.07.25'
|
|
48
48
|
|
|
49
49
|
_height0_ = _height_ + _0_
|
|
50
50
|
_narrow_ = 'narrow'
|
|
@@ -722,15 +722,15 @@ class _ChLV(object):
|
|
|
722
722
|
t = Y_X_h_lat_lon_h + (self, self._t0, None) # PYCHOK _t0
|
|
723
723
|
return ChLV9Tuple(t, name=name)
|
|
724
724
|
|
|
725
|
-
@
|
|
725
|
+
@property_ROver
|
|
726
726
|
def _enh_n_h(self):
|
|
727
727
|
'''(INTERNAL) Get C{ChLV*.reverse} args[1:4] names, I{once}.
|
|
728
728
|
'''
|
|
729
|
-
|
|
729
|
+
t = _args_kwds_names(_ChLV.reverse)[1:4]
|
|
730
730
|
# assert _args_kwds_names( ChLV.reverse)[1:4] == t
|
|
731
731
|
# assert _args_kwds_names(ChLVa.reverse)[1:4] == t
|
|
732
732
|
# assert _args_kwds_names(ChLVe.reverse)[1:4] == t
|
|
733
|
-
return t
|
|
733
|
+
return t # overwrite property_ROver
|
|
734
734
|
|
|
735
735
|
def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
|
|
736
736
|
'''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
|
pygeodesy/ltpTuples.py
CHANGED
|
@@ -28,15 +28,15 @@ from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
|
|
|
28
28
|
from pygeodesy.props import deprecated_method, deprecated_Property_RO, \
|
|
29
29
|
Property_RO, property_RO
|
|
30
30
|
from pygeodesy.streprs import Fmt, fstr, strs, _xzipairs
|
|
31
|
-
from pygeodesy.units import Bearing, Degrees, Degrees_, Height,
|
|
32
|
-
_isMeter, Lat, Lon, Meter, Meter_
|
|
31
|
+
from pygeodesy.units import Azimuth, Bearing, Degrees, Degrees_, Height, \
|
|
32
|
+
_isDegrees, _isMeter, Lat, Lon, Meter, Meter_
|
|
33
33
|
from pygeodesy.utily import atan2d, atan2b, sincos2_, sincos2d_, cos, radians
|
|
34
34
|
from pygeodesy.vector3d import Vector3d
|
|
35
35
|
|
|
36
36
|
# from math import cos, radians # from .utily
|
|
37
37
|
|
|
38
38
|
__all__ = _ALL_LAZY.ltpTuples
|
|
39
|
-
__version__ = '24.
|
|
39
|
+
__version__ = '24.07.25'
|
|
40
40
|
|
|
41
41
|
_aer_ = 'aer'
|
|
42
42
|
_alt_ = 'alt'
|
|
@@ -93,7 +93,7 @@ def _xyz2aer4(inst):
|
|
|
93
93
|
'''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
|
|
94
94
|
'''
|
|
95
95
|
x, y, z, _ = inst.xyz4
|
|
96
|
-
A =
|
|
96
|
+
A = Azimuth(atan2b(x, y))
|
|
97
97
|
E = Degrees(elevation=atan2d(z, hypot(x, y)))
|
|
98
98
|
R = Meter(slantrange=hypot_(x, y, z))
|
|
99
99
|
return Aer4Tuple(A, E, R, inst.ltp, name=inst.name)
|
|
@@ -268,7 +268,7 @@ class Aer(_AbcBase):
|
|
|
268
268
|
'''
|
|
269
269
|
if _isDegrees(azimuth_aer):
|
|
270
270
|
aer = None
|
|
271
|
-
t = (
|
|
271
|
+
t = (Azimuth(azimuth_aer),
|
|
272
272
|
Degrees_(elevation=elevation, low=_N_90_0, high=_90_0),
|
|
273
273
|
Meter_(slantrange=slantrange), ltp)
|
|
274
274
|
else: # PYCHOK no cover
|
|
@@ -421,7 +421,7 @@ class Attitude4Tuple(_NamedTuple):
|
|
|
421
421
|
the attitude of a plane or camera.
|
|
422
422
|
'''
|
|
423
423
|
_Names_ = (_alt_, _tilt_, _yaw_, _roll_)
|
|
424
|
-
_Units_ = ( Meter,
|
|
424
|
+
_Units_ = ( Meter, Degrees, Bearing, Degrees)
|
|
425
425
|
|
|
426
426
|
@Property_RO
|
|
427
427
|
def atyr(self):
|
pygeodesy/named.py
CHANGED
|
@@ -34,7 +34,7 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
|
|
|
34
34
|
# from pygeodesy.units import _toUnit # _MODS
|
|
35
35
|
|
|
36
36
|
__all__ = _ALL_LAZY.named
|
|
37
|
-
__version__ = '24.
|
|
37
|
+
__version__ = '24.07.12'
|
|
38
38
|
|
|
39
39
|
_COMMANL_ = _COMMA_ + _NL_
|
|
40
40
|
_COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
|
|
@@ -1231,9 +1231,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
|
|
|
1231
1231
|
@return: The B{C{class}}'s C{[module.]class} name (C{str}).
|
|
1232
1232
|
'''
|
|
1233
1233
|
try:
|
|
1234
|
-
n =
|
|
1234
|
+
n = clas.__name__
|
|
1235
1235
|
except AttributeError:
|
|
1236
|
-
n = _dunder_name_
|
|
1236
|
+
n = clas if isstr(clas) else _dunder_name_
|
|
1237
1237
|
if prefixed or (classnaming() if prefixed is None else False):
|
|
1238
1238
|
try:
|
|
1239
1239
|
m = clas.__module__.rsplit(_DOT_, 1)
|
pygeodesy/nvectorBase.py
CHANGED
|
@@ -29,7 +29,7 @@ from pygeodesy.named import _xother3, _under
|
|
|
29
29
|
from pygeodesy.namedTuples import Trilaterate5Tuple, Vector3Tuple, \
|
|
30
30
|
Vector4Tuple, map1
|
|
31
31
|
from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
|
|
32
|
-
property_RO, _update_all
|
|
32
|
+
property_RO, property_ROnce, _update_all
|
|
33
33
|
from pygeodesy.streprs import Fmt, hstr, unstr
|
|
34
34
|
from pygeodesy.units import Bearing, Height, Radius_, Scalar
|
|
35
35
|
from pygeodesy.utily import sincos2d, _unrollon, _unrollon3
|
|
@@ -38,7 +38,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
|
38
38
|
from math import fabs, sqrt
|
|
39
39
|
|
|
40
40
|
__all__ = _ALL_LAZY.nvectorBase
|
|
41
|
-
__version__ = '24.
|
|
41
|
+
__version__ = '24.07.12'
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class NvectorBase(Vector3d): # XXX kept private
|
|
@@ -78,12 +78,11 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
78
78
|
'''
|
|
79
79
|
return self._datum
|
|
80
80
|
|
|
81
|
-
@
|
|
81
|
+
@property_ROnce
|
|
82
82
|
def Ecef(self):
|
|
83
83
|
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
84
84
|
'''
|
|
85
|
-
|
|
86
|
-
return E
|
|
85
|
+
return _MODS.ecef.EcefKarney
|
|
87
86
|
|
|
88
87
|
@property_RO
|
|
89
88
|
def ellipsoidalNvector(self):
|
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
|
@@ -21,7 +21,7 @@ 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
27
|
class _RhumbSolveBase(_SolveGDictBase):
|
|
@@ -173,7 +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 I{without} C{
|
|
176
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but I{without} C{_SALP_CALPs_}.
|
|
177
177
|
'''
|
|
178
178
|
i = _RhumbSolveBase._GDictInverse(self, lat1, lon1, lat2, lon2, **floats)
|
|
179
179
|
a = _over(float(i.s12), self._mpd) # for .Inverse1
|
pygeodesy/solveBase.py
CHANGED
|
@@ -11,8 +11,9 @@ from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
|
11
11
|
from pygeodesy.errors import _AssertionError, _xkwds_get, _xkwds_get1, \
|
|
12
12
|
_xkwds_item2
|
|
13
13
|
from pygeodesy.internals import _enquote, printf
|
|
14
|
-
from pygeodesy.interns import NN, _0_, _BACKSLASH_,
|
|
15
|
-
_EQUAL_, _Error_, _SPACE_,
|
|
14
|
+
from pygeodesy.interns import NN, _0_, _AT_,_BACKSLASH_, _COLONSPACE_, \
|
|
15
|
+
_COMMASPACE_, _EQUAL_, _Error_, _SPACE_, \
|
|
16
|
+
_UNUSED_
|
|
16
17
|
from pygeodesy.karney import Caps, _CapsBase, GDict
|
|
17
18
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _sys_version_info2
|
|
18
19
|
from pygeodesy.named import callername, _name2__, notOverloaded
|
|
@@ -24,7 +25,7 @@ from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
|
|
|
24
25
|
from subprocess import PIPE as _PIPE, Popen as _Popen, STDOUT as _STDOUT
|
|
25
26
|
|
|
26
27
|
__all__ = _ALL_LAZY.solveBase
|
|
27
|
-
__version__ = '24.07.
|
|
28
|
+
__version__ = '24.07.11'
|
|
28
29
|
|
|
29
30
|
_ERROR_ = 'ERROR'
|
|
30
31
|
_Popen_kwds = dict(creationflags=0,
|
|
@@ -54,7 +55,7 @@ def _cmd_stdin_(cmd, stdin): # PYCHOK no cover
|
|
|
54
55
|
|
|
55
56
|
def _popen2(cmd, stdin=None): # in .mgrs, test.bases, .testMgrs
|
|
56
57
|
'''(INTERNAL) Invoke C{B{cmd} tuple} and return C{exitcode}
|
|
57
|
-
and all output from C{stdout/-err}.
|
|
58
|
+
and all output from C{stdout/-err}, I{stripped}.
|
|
58
59
|
'''
|
|
59
60
|
p = _Popen(cmd, **_Popen_kwds) # PYCHOK kwArgs
|
|
60
61
|
r = p.communicate(stdin)[0] # stdout + NL + stderr
|
|
@@ -67,6 +68,7 @@ class _SolveCapsBase(_CapsBase):
|
|
|
67
68
|
_datum = _WGS84
|
|
68
69
|
_Error = None
|
|
69
70
|
_Exact = True
|
|
71
|
+
_invokat = _AT_
|
|
70
72
|
_invokation = 0
|
|
71
73
|
_linelimit = 0
|
|
72
74
|
_prec = Precision_(prec=DIG)
|
|
@@ -100,7 +102,7 @@ class _SolveCapsBase(_CapsBase):
|
|
|
100
102
|
v = map(float, v) # _float_int, see Intersectool._XDistInvoke
|
|
101
103
|
return Dict(_zip(n, v)) # strict=True
|
|
102
104
|
|
|
103
|
-
def _DictInvoke2(self, cmd, Names, Dict,
|
|
105
|
+
def _DictInvoke2(self, cmd, args, Names, Dict, **floats_R):
|
|
104
106
|
'''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
|
|
105
107
|
'''
|
|
106
108
|
N = len(Names)
|
|
@@ -172,6 +174,16 @@ class _SolveCapsBase(_CapsBase):
|
|
|
172
174
|
|
|
173
175
|
f = flattening
|
|
174
176
|
|
|
177
|
+
def invokat(self, *prefix):
|
|
178
|
+
'''Get and set the invokation number C{"@"} prefix (C{str}).
|
|
179
|
+
|
|
180
|
+
@return: Previous prefix (C{str}).
|
|
181
|
+
'''
|
|
182
|
+
p = self._invokat
|
|
183
|
+
if prefix:
|
|
184
|
+
set._invokat = str(prefix[0])
|
|
185
|
+
return p
|
|
186
|
+
|
|
175
187
|
@property_RO
|
|
176
188
|
def invokation(self):
|
|
177
189
|
'''Get the most recent C{Solve} invokation number (C{int}).
|
|
@@ -223,7 +235,7 @@ class _SolveCapsBase(_CapsBase):
|
|
|
223
235
|
raise self._Error(cmd=t or _cmd_stdin_(cmd, stdin), cause=x)
|
|
224
236
|
self._status = s
|
|
225
237
|
if self.verbose: # and _R is None: # PYCHOK no cover
|
|
226
|
-
self._print(repr(r))
|
|
238
|
+
self._print(repr(r), 'stdout/-err')
|
|
227
239
|
return r
|
|
228
240
|
|
|
229
241
|
def linelimit(self, *limit):
|
|
@@ -268,14 +280,16 @@ class _SolveCapsBase(_CapsBase):
|
|
|
268
280
|
_update_all(self)
|
|
269
281
|
self._prec = prec
|
|
270
282
|
|
|
271
|
-
def _print(self, line): # PYCHOK no cover
|
|
283
|
+
def _print(self, line, *suffix): # PYCHOK no cover
|
|
272
284
|
'''(INTERNAL) Print a status line.
|
|
273
285
|
'''
|
|
274
286
|
if self._linelimit:
|
|
275
287
|
line = clips(line, limit=self._linelimit, length=True)
|
|
276
288
|
if self.status is not None:
|
|
277
|
-
|
|
278
|
-
|
|
289
|
+
s = _COMMASPACE_(self.status, *suffix)
|
|
290
|
+
line = _SPACE_(line, Fmt.PAREN(s))
|
|
291
|
+
p = NN(self.named2, self._invokat, self.invokation)
|
|
292
|
+
printf(_COLONSPACE_(p, line))
|
|
279
293
|
|
|
280
294
|
def _setXable(self, path, **Xable_path):
|
|
281
295
|
'''(INTERNAL) Set the executable C{path}.
|
|
@@ -411,7 +425,7 @@ class _SolveGDictBase(_SolveBase):
|
|
|
411
425
|
lat, lon, azi, s12_a12, **floats)
|
|
412
426
|
|
|
413
427
|
def _GDictInverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
|
|
414
|
-
'''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but I{without} C{
|
|
428
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but I{without} C{_SALP_CALPs_}.
|
|
415
429
|
'''
|
|
416
430
|
return self._GDictInvoke(self._cmdInverse, self._Names_Inverse,
|
|
417
431
|
lat1, lon1, lat2, lon2, **floats)
|
|
@@ -419,7 +433,7 @@ class _SolveGDictBase(_SolveBase):
|
|
|
419
433
|
def _GDictInvoke(self, cmd, Names, *args, **floats):
|
|
420
434
|
'''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
|
|
421
435
|
'''
|
|
422
|
-
return self._DictInvoke2(cmd, Names, GDict,
|
|
436
|
+
return self._DictInvoke2(cmd, args, Names, GDict, **floats)[0] # _R
|
|
423
437
|
|
|
424
438
|
def Inverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_): # PYCHOK unused
|
|
425
439
|
'''Return the C{Inverse} result.
|
|
@@ -456,7 +470,7 @@ class _SolveGDictLineBase(_SolveGDictBase):
|
|
|
456
470
|
if name:
|
|
457
471
|
self.name = name
|
|
458
472
|
|
|
459
|
-
self._caps = caps | Caps.
|
|
473
|
+
self._caps = caps | Caps._AZIMUTH_LATITUDE_LONG_UNROLL
|
|
460
474
|
self._debug = solve._debug & Caps._DEBUG_ALL
|
|
461
475
|
self._lla1 = GDict(lat1=lat1, lon1=lon1, **azi)
|
|
462
476
|
self._solve = solve
|
pygeodesy/triaxials.py
CHANGED
|
@@ -49,7 +49,7 @@ from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, \
|
|
|
49
49
|
_NamedEnumItem, _Pass
|
|
50
50
|
from pygeodesy.namedTuples import LatLon3Tuple, _NamedTupleTo, Vector3Tuple, \
|
|
51
51
|
Vector4Tuple
|
|
52
|
-
from pygeodesy.props import Property_RO,
|
|
52
|
+
from pygeodesy.props import Property_RO, property_ROver
|
|
53
53
|
# from pygeodesy.streprs import Fmt # from .datums
|
|
54
54
|
from pygeodesy.units import Degrees, Float, Height_, Meter, Meter2, Meter3, \
|
|
55
55
|
Radians, Radius, Scalar_
|
|
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
|
|
|
59
59
|
from math import atan2, fabs, sqrt
|
|
60
60
|
|
|
61
61
|
__all__ = _ALL_LAZY.triaxials
|
|
62
|
-
__version__ = '24.
|
|
62
|
+
__version__ = '24.07.29'
|
|
63
63
|
|
|
64
64
|
_not_ordered_ = _not_('ordered')
|
|
65
65
|
_omega_ = 'omega'
|
|
@@ -360,12 +360,11 @@ class Triaxial_(_NamedEnumItem):
|
|
|
360
360
|
|
|
361
361
|
_1e2bc = _c2_b2 # C{1 - e2bc} == C{(c/b)**2}
|
|
362
362
|
|
|
363
|
-
@
|
|
363
|
+
@property_ROver
|
|
364
364
|
def _Elliptic(self):
|
|
365
365
|
'''(INTERNAL) Get class L{Elliptic}, I{once}.
|
|
366
366
|
'''
|
|
367
|
-
|
|
368
|
-
return E
|
|
367
|
+
return _MODS.elliptic.Elliptic # overwrite property_ROver
|
|
369
368
|
|
|
370
369
|
def hartzell4(self, pov, los=False, **name):
|
|
371
370
|
'''Compute the intersection of this triaxial's surface with a Line-Of-Sight
|
|
@@ -754,7 +753,7 @@ class Triaxial(Triaxial_):
|
|
|
754
753
|
return self.height4(x_xyz, y, z, **normal_eps_name)
|
|
755
754
|
|
|
756
755
|
def forwardLatLon(self, lat, lon, height=0, **name):
|
|
757
|
-
'''Convert I{geodetic} lat-, longitude and
|
|
756
|
+
'''Convert I{geodetic} lat-, longitude and height to cartesian.
|
|
758
757
|
|
|
759
758
|
@arg lat: Geodetic latitude (C{degrees}).
|
|
760
759
|
@arg lon: Geodetic longitude (C{degrees}).
|
|
@@ -770,7 +769,7 @@ class Triaxial(Triaxial_):
|
|
|
770
769
|
return self._forwardLatLon3(height, name, *sincos2d_(lat, lon))
|
|
771
770
|
|
|
772
771
|
def forwardLatLon_(self, slat, clat, slon, clon, height=0, **name):
|
|
773
|
-
'''Convert I{geodetic} lat-, longitude and
|
|
772
|
+
'''Convert I{geodetic} lat-, longitude and height to cartesian.
|
|
774
773
|
|
|
775
774
|
@arg slat: Geodetic latitude C{sin(lat)} (C{scalar}).
|
|
776
775
|
@arg clat: Geodetic latitude C{cos(lat)} (C{scalar}).
|