pygeodesy 24.5.15__py2.py3-none-any.whl → 24.6.1__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.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
- PyGeodesy-24.6.1.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +4 -4
- pygeodesy/albers.py +41 -41
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +32 -31
- pygeodesy/auxilats/auxLat.py +80 -51
- pygeodesy/azimuthal.py +123 -124
- pygeodesy/basics.py +46 -10
- pygeodesy/booleans.py +13 -14
- pygeodesy/cartesianBase.py +25 -23
- pygeodesy/clipy.py +3 -3
- pygeodesy/constants.py +3 -3
- pygeodesy/css.py +50 -42
- pygeodesy/datums.py +42 -41
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/dms.py +6 -6
- pygeodesy/ecef.py +41 -41
- pygeodesy/ellipsoidalBase.py +41 -41
- pygeodesy/ellipsoidalBaseDI.py +3 -4
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoidalNvector.py +11 -12
- pygeodesy/ellipsoids.py +45 -38
- pygeodesy/elliptic.py +3 -4
- pygeodesy/epsg.py +4 -3
- pygeodesy/errors.py +52 -20
- pygeodesy/etm.py +68 -65
- pygeodesy/fmath.py +44 -49
- pygeodesy/formy.py +129 -115
- pygeodesy/frechet.py +118 -103
- pygeodesy/fstats.py +21 -14
- pygeodesy/fsums.py +124 -80
- pygeodesy/gars.py +10 -9
- pygeodesy/geodesicw.py +19 -17
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +39 -33
- pygeodesy/geodesicx/gxarea.py +12 -9
- pygeodesy/geodesicx/gxbases.py +3 -4
- pygeodesy/geodesicx/gxline.py +6 -8
- pygeodesy/geodsolve.py +29 -28
- pygeodesy/geohash.py +60 -57
- pygeodesy/geoids.py +34 -32
- pygeodesy/hausdorff.py +114 -101
- pygeodesy/heights.py +137 -130
- pygeodesy/internals.py +16 -11
- pygeodesy/interns.py +3 -6
- pygeodesy/iters.py +19 -17
- pygeodesy/karney.py +21 -17
- pygeodesy/ktm.py +25 -18
- pygeodesy/latlonBase.py +12 -11
- pygeodesy/lazily.py +6 -6
- pygeodesy/lcc.py +24 -25
- pygeodesy/ltp.py +143 -113
- pygeodesy/ltpTuples.py +207 -150
- pygeodesy/mgrs.py +26 -26
- pygeodesy/named.py +172 -90
- pygeodesy/namedTuples.py +33 -25
- pygeodesy/nvectorBase.py +8 -8
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +18 -18
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +13 -10
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +18 -18
- pygeodesy/sphericalBase.py +17 -21
- pygeodesy/sphericalTrigonometry.py +21 -21
- pygeodesy/streprs.py +5 -5
- pygeodesy/trf.py +13 -11
- pygeodesy/triaxials.py +68 -64
- pygeodesy/units.py +35 -35
- pygeodesy/unitsBase.py +24 -11
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +3 -3
- pygeodesy/utm.py +183 -187
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +104 -106
- pygeodesy/vector2d.py +6 -7
- pygeodesy/vector3d.py +16 -17
- pygeodesy/vector3dBase.py +4 -5
- pygeodesy/webmercator.py +43 -51
- PyGeodesy-24.5.15.dist-info/RECORD +0 -116
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/datums.py
CHANGED
|
@@ -73,8 +73,7 @@ from pygeodesy.constants import R_M, _float as _F, _0_0, _1_0, _2_0, _8_0, _3600
|
|
|
73
73
|
# LatLonEllipsoidalBase as _LLEB # MODS
|
|
74
74
|
from pygeodesy.ellipsoids import a_f2Tuple, Ellipsoid, Ellipsoid2, Ellipsoids, _EWGS84, \
|
|
75
75
|
Vector3Tuple
|
|
76
|
-
from pygeodesy.errors import _IsnotError, _TypeError,
|
|
77
|
-
_xkwds_pop2
|
|
76
|
+
from pygeodesy.errors import _IsnotError, _TypeError, _xellipsoidall, _xkwds, _xkwds_pop2
|
|
78
77
|
from pygeodesy.fmath import fdot, fmean, Fmt, _operator
|
|
79
78
|
from pygeodesy.internals import _passarg, _under
|
|
80
79
|
from pygeodesy.interns import NN, _a_, _Airy1830_, _AiryModified_, _BAR_, _Bessel1841_, \
|
|
@@ -84,7 +83,8 @@ from pygeodesy.interns import NN, _a_, _Airy1830_, _AiryModified_, _BAR_, _Besse
|
|
|
84
83
|
_PLUS_, _Sphere_, _spherical_, _transform_, _UNDER_, \
|
|
85
84
|
_WGS72_, _WGS84_
|
|
86
85
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
87
|
-
from pygeodesy.named import
|
|
86
|
+
from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _name2__, _NamedEnum, \
|
|
87
|
+
_NamedEnumItem
|
|
88
88
|
# from pygeodesy.namedTuples import Vector3Tuple # from .ellipsoids
|
|
89
89
|
from pygeodesy.props import Property_RO, property_RO
|
|
90
90
|
# from pygeodesy.streprs import Fmt # from .fmath
|
|
@@ -94,7 +94,7 @@ from pygeodesy.units import _isRadius, Radius_, radians
|
|
|
94
94
|
# import operator as _operator # from .fmath
|
|
95
95
|
|
|
96
96
|
__all__ = _ALL_LAZY.datums
|
|
97
|
-
__version__ = '24.05.
|
|
97
|
+
__version__ = '24.05.21'
|
|
98
98
|
|
|
99
99
|
_a_ellipsoid_ = _UNDER_(_a_, _ellipsoid_)
|
|
100
100
|
_BD72_ = 'BD72'
|
|
@@ -204,15 +204,15 @@ class Transform(_NamedEnumItem):
|
|
|
204
204
|
def __neg__(self):
|
|
205
205
|
return self.inverse()
|
|
206
206
|
|
|
207
|
-
def inverse(self, name
|
|
207
|
+
def inverse(self, **name):
|
|
208
208
|
'''Return the inverse of this transform.
|
|
209
209
|
|
|
210
210
|
@kwarg name: Optional, unique name (C{str}).
|
|
211
211
|
|
|
212
212
|
@return: Inverse (L{Transform}), unregistered.
|
|
213
213
|
'''
|
|
214
|
-
r =
|
|
215
|
-
n = name or _negastr(self.name)
|
|
214
|
+
r = type(self)(**dict(self.items(inverse=True)))
|
|
215
|
+
n = _name__(**name) or _negastr(self.name)
|
|
216
216
|
if n:
|
|
217
217
|
r.name = n # unregistered
|
|
218
218
|
return r
|
|
@@ -248,16 +248,17 @@ class Transform(_NamedEnumItem):
|
|
|
248
248
|
self.s = s = (s1 - _1_0) / _S1_S
|
|
249
249
|
return s
|
|
250
250
|
|
|
251
|
-
def toStr(self, prec=5, fmt=Fmt.g, name
|
|
251
|
+
def toStr(self, prec=5, fmt=Fmt.g, **name): # PYCHOK expected
|
|
252
252
|
'''Return this transform as a string.
|
|
253
253
|
|
|
254
254
|
@kwarg prec: Number of (decimal) digits, unstripped (C{int}).
|
|
255
255
|
@kwarg fmt: Optional C{float} format (C{letter}).
|
|
256
|
-
@kwarg name:
|
|
257
|
-
this transform's name.
|
|
256
|
+
@kwarg name: Optional, override C{B{name}=NN} (C{str}) or
|
|
257
|
+
C{None} to exclude this transform's name.
|
|
258
258
|
|
|
259
259
|
@return: Transform attributes (C{str}).
|
|
260
260
|
'''
|
|
261
|
+
name, _ = _name2__(**name) # name=None
|
|
261
262
|
return self._instr(name, prec, *_Names11, fmt=fmt)
|
|
262
263
|
|
|
263
264
|
def transform(self, x, y, z, inverse=False, **Vector_and_kwds):
|
|
@@ -378,12 +379,12 @@ class Datum(_NamedEnumItem):
|
|
|
378
379
|
_ellipsoid = Ellipsoids.WGS84 # default ellipsoid (L{Ellipsoid}, L{Ellipsoid2})
|
|
379
380
|
_transform = Transforms.WGS84 # default transform (L{Transform})
|
|
380
381
|
|
|
381
|
-
def __init__(self, ellipsoid, transform=None, name
|
|
382
|
+
def __init__(self, ellipsoid, transform=None, **name):
|
|
382
383
|
'''New L{Datum}.
|
|
383
384
|
|
|
384
385
|
@arg ellipsoid: The ellipsoid (L{Ellipsoid} or L{Ellipsoid2}).
|
|
385
386
|
@kwarg transform: Optional transform (L{Transform}).
|
|
386
|
-
@kwarg name: Optional, unique name (C{str}).
|
|
387
|
+
@kwarg name: Optional, unique C{B{name}=NN} (C{str}).
|
|
387
388
|
|
|
388
389
|
@raise NameError: Datum with that B{C{name}} already exists.
|
|
389
390
|
|
|
@@ -397,7 +398,8 @@ class Datum(_NamedEnumItem):
|
|
|
397
398
|
self._transform = transform or Datum._transform
|
|
398
399
|
_xinstanceof(Transform, transform=self.transform)
|
|
399
400
|
|
|
400
|
-
self._register(Datums, name or self.transform.name
|
|
401
|
+
self._register(Datums, _name__(name) or self.transform.name
|
|
402
|
+
or self.ellipsoid.name)
|
|
401
403
|
|
|
402
404
|
def __eq__(self, other):
|
|
403
405
|
'''Compare this and an other datum.
|
|
@@ -474,15 +476,16 @@ class Datum(_NamedEnumItem):
|
|
|
474
476
|
'''
|
|
475
477
|
return self.ellipsoid.isSpherical
|
|
476
478
|
|
|
477
|
-
def toStr(self, sep=_COMMASPACE_, name
|
|
479
|
+
def toStr(self, sep=_COMMASPACE_, **name): # PYCHOK expected
|
|
478
480
|
'''Return this datum as a string.
|
|
479
481
|
|
|
480
482
|
@kwarg sep: Separator to join (C{str}).
|
|
481
|
-
@kwarg name:
|
|
482
|
-
this datum's name.
|
|
483
|
+
@kwarg name: Optional, override C{B{name}=NN} (C{str}) or
|
|
484
|
+
C{None} to exclude this datum's name.
|
|
483
485
|
|
|
484
486
|
@return: Datum attributes (C{str}).
|
|
485
487
|
'''
|
|
488
|
+
name, _ = _name2__(**name) # name=None
|
|
486
489
|
t = [] if name is None else \
|
|
487
490
|
[Fmt.EQUAL(name=repr(name or self.named))]
|
|
488
491
|
for a in (_ellipsoid_, _transform_):
|
|
@@ -497,7 +500,7 @@ class Datum(_NamedEnumItem):
|
|
|
497
500
|
return self._transform
|
|
498
501
|
|
|
499
502
|
|
|
500
|
-
def _earth_datum(inst, a_earth, f=None,
|
|
503
|
+
def _earth_datum(inst, a_earth, f=None, raiser=_a_ellipsoid_, **name): # in .karney, .trf, ...
|
|
501
504
|
'''(INTERNAL) Set C{inst._datum} from C{(B{a_..}, B{f})} or C{B{.._ellipsoid}}
|
|
502
505
|
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum}, C{a_f2Tuple} or C{scalar} earth radius).
|
|
503
506
|
|
|
@@ -520,12 +523,12 @@ def _earth_datum(inst, a_earth, f=None, name=NN, raiser=_a_ellipsoid_): # in .k
|
|
|
520
523
|
inst._datum = D
|
|
521
524
|
|
|
522
525
|
|
|
523
|
-
def _earth_ellipsoid(earth,
|
|
526
|
+
def _earth_ellipsoid(earth, **name_raiser):
|
|
524
527
|
'''(INTERAL) Return the ellipsoid for the given C{earth} model.
|
|
525
528
|
'''
|
|
526
529
|
return Ellipsoids.Sphere if earth is R_M else (
|
|
527
530
|
_EWGS84 if earth is _EWGS84 or earth is _WGS84 else
|
|
528
|
-
_spherical_datum(earth,
|
|
531
|
+
_spherical_datum(earth, **name_raiser).ellipsoid)
|
|
529
532
|
|
|
530
533
|
|
|
531
534
|
def _ED2(radius, name):
|
|
@@ -534,13 +537,13 @@ def _ED2(radius, name):
|
|
|
534
537
|
D = Datums.Sphere
|
|
535
538
|
E = D.ellipsoid
|
|
536
539
|
if name or radius != E.a: # != E.b
|
|
537
|
-
n = _under(name)
|
|
540
|
+
n = _under(_name__(name, _or_nameof=D))
|
|
538
541
|
E = Ellipsoid(radius, radius, name=n)
|
|
539
542
|
D = Datum(E, transform=Transforms.Identity, name=n)
|
|
540
543
|
return E, D
|
|
541
544
|
|
|
542
545
|
|
|
543
|
-
def _ellipsoidal_datum(earth, Error=TypeError,
|
|
546
|
+
def _ellipsoidal_datum(earth, Error=TypeError, raiser=NN, **name):
|
|
544
547
|
'''(INTERNAL) Create a L{Datum} from an L{Ellipsoid} or L{Ellipsoid2},
|
|
545
548
|
C{a_f2Tuple}, 2-tuple or 2-list B{C{earth}} model.
|
|
546
549
|
|
|
@@ -563,29 +566,25 @@ def _ellipsoidal_datum(earth, Error=TypeError, name=NN, raiser=NN):
|
|
|
563
566
|
def _EnD3(earth, name):
|
|
564
567
|
'''(INTERNAL) Helper for C{_earth_datum} and C{_ellipsoidal_datum}.
|
|
565
568
|
'''
|
|
566
|
-
D = None
|
|
569
|
+
D, n = None, _under(_name__(name, _or_nameof=earth))
|
|
567
570
|
if isinstance(earth, (Ellipsoid, Ellipsoid2)):
|
|
568
|
-
E =
|
|
569
|
-
n = _under(name or E.name)
|
|
571
|
+
E = earth
|
|
570
572
|
elif isinstance(earth, Datum):
|
|
571
|
-
E =
|
|
572
|
-
|
|
573
|
-
D = earth
|
|
573
|
+
E = earth.ellipsoid
|
|
574
|
+
D = earth
|
|
574
575
|
elif _isRadius(earth):
|
|
575
|
-
E, D = _ED2(Radius_(earth),
|
|
576
|
-
n =
|
|
576
|
+
E, D = _ED2(Radius_(earth), n)
|
|
577
|
+
n = E.name
|
|
577
578
|
elif isinstance(earth, a_f2Tuple):
|
|
578
|
-
|
|
579
|
-
E = earth.ellipsoid(name=n)
|
|
579
|
+
E = earth.ellipsoid(name=n)
|
|
580
580
|
elif islistuple(earth, minum=2):
|
|
581
|
-
E =
|
|
581
|
+
E = Ellipsoids.Sphere
|
|
582
582
|
a, f = earth[:2]
|
|
583
583
|
if f or a != E.a: # != E.b
|
|
584
|
-
|
|
585
|
-
E = Ellipsoid(a, f=f, name=n)
|
|
584
|
+
E = Ellipsoid(a, f=f, name=n)
|
|
586
585
|
else:
|
|
587
|
-
n =
|
|
588
|
-
D =
|
|
586
|
+
n = E.name
|
|
587
|
+
D = Datums.Sphere
|
|
589
588
|
else:
|
|
590
589
|
E, n = None, NN
|
|
591
590
|
return E, n, D
|
|
@@ -624,16 +623,18 @@ def _negastr(name): # in .trf
|
|
|
624
623
|
return n.lstrip(p) if n.startswith(p) else NN(m, n)
|
|
625
624
|
|
|
626
625
|
|
|
627
|
-
def _spherical_datum(earth, Error=TypeError,
|
|
626
|
+
def _spherical_datum(earth, Error=TypeError, raiser=NN, **name):
|
|
628
627
|
'''(INTERNAL) Create a L{Datum} from an L{Ellipsoid}, L{Ellipsoid2},
|
|
629
628
|
C{a_f2Tuple}, 2-tuple, 2-list B{C{earth}} model or C{scalar} radius.
|
|
630
629
|
|
|
631
630
|
@kwarg raiser: If not C{NN}, raise an B{C{Error}} if not spherical.
|
|
632
631
|
'''
|
|
633
|
-
if
|
|
632
|
+
if isinstance(earth, Datum):
|
|
633
|
+
D = earth
|
|
634
|
+
elif _isRadius(earth):
|
|
634
635
|
_, D = _ED2(Radius_(earth, Error=Error), name)
|
|
635
636
|
else:
|
|
636
|
-
D = _ellipsoidal_datum(earth, Error=Error, name
|
|
637
|
+
D = _ellipsoidal_datum(earth, Error=Error, **name)
|
|
637
638
|
if raiser and not D.isSpherical:
|
|
638
639
|
raise _IsnotError(_spherical_, Error=Error, **{raiser: earth})
|
|
639
640
|
return D
|
|
@@ -643,11 +644,11 @@ class Datums(_NamedEnum):
|
|
|
643
644
|
'''(INTERNAL) L{Datum} registry, I{must} be a sub-class
|
|
644
645
|
to accommodate the L{_LazyNamedEnumItem} properties.
|
|
645
646
|
'''
|
|
646
|
-
def _Lazy(self, ellipsoid_name, transform_name, name
|
|
647
|
+
def _Lazy(self, ellipsoid_name, transform_name, **name):
|
|
647
648
|
'''(INTERNAL) Instantiate the L{Datum}.
|
|
648
649
|
'''
|
|
649
650
|
return Datum(Ellipsoids.get(ellipsoid_name),
|
|
650
|
-
Transforms.get(transform_name), name
|
|
651
|
+
Transforms.get(transform_name), **name)
|
|
651
652
|
|
|
652
653
|
Datums = Datums(Datum) # PYCHOK singleton
|
|
653
654
|
'''Some pre-defined L{Datum}s, all I{lazily} instantiated.'''
|
|
@@ -14,7 +14,7 @@ from pygeodesy.props import deprecated_function
|
|
|
14
14
|
from pygeodesy.units import Number_, Scalar_
|
|
15
15
|
|
|
16
16
|
__all__ = _ALL_DEPRECATED.deprecated_functions
|
|
17
|
-
__version__ = '24.
|
|
17
|
+
__version__ = '24.05.25'
|
|
18
18
|
|
|
19
19
|
_WGS84 = _UTM = object()
|
|
20
20
|
|
|
@@ -109,13 +109,19 @@ def enStr2(easting, northing, prec, *extras): # PYCHOK no cover
|
|
|
109
109
|
return _MODS.streprs.enstr2(easting, northing, (int(prec) // 2 - 5), *extras)
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
@deprecated_function
|
|
113
|
+
def equirectangular_(lat1, lon1, lat2, lon2, **options): # PYCHOK no cover
|
|
114
|
+
'''DEPRECATED on 2024.05.25, use function L{pygeodesy.equirectangular4}.'''
|
|
115
|
+
return _MODS.formy.equirectangular4(lat1, lon1, lat2, lon2, **options)
|
|
116
|
+
|
|
117
|
+
|
|
112
118
|
@deprecated_function
|
|
113
119
|
def equirectangular3(lat1, lon1, lat2, lon2, **options): # PYCHOK no cover
|
|
114
|
-
'''DEPRECATED, use function L{pygeodesy.
|
|
120
|
+
'''DEPRECATED, use function L{pygeodesy.equirectangular4}.
|
|
115
121
|
|
|
116
122
|
@return: 3-Tuple C{(distance2, delta_lat, delta_lon)}.
|
|
117
123
|
'''
|
|
118
|
-
return tuple(_MODS.formy.
|
|
124
|
+
return tuple(_MODS.formy.equirectangular4(lat1, lon1, lat2, lon2, **options)[:3])
|
|
119
125
|
|
|
120
126
|
|
|
121
127
|
@deprecated_function
|
pygeodesy/dms.py
CHANGED
|
@@ -66,10 +66,11 @@ from pygeodesy.basics import copysign0, isLatLon, isodd, issequence, isstr, map2
|
|
|
66
66
|
from pygeodesy.constants import _umod_360, _0_0, _0_5, _60_0, _360_0, _3600_0
|
|
67
67
|
from pygeodesy.errors import ParseError, RangeError, _TypeError, _ValueError,\
|
|
68
68
|
_parseX, rangerrors, _xkwds, _xkwds_get
|
|
69
|
-
from pygeodesy.interns import NN, _arg_, _COMMA_, _d_, _DASH_, _deg_, _degrees_,
|
|
70
|
-
_0_, _e_, _E_, _EW_, _f_, _F_, _g_,
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
from pygeodesy.interns import NN, _arg_, _COMMA_, _d_, _DASH_, _deg_, _degrees_, \
|
|
70
|
+
_DOT_, _0_, _e_, _E_, _EW_, _f_, _F_, _g_, _keyword_, \
|
|
71
|
+
_MINUS_, _N_, _NE_, _NS_, _NSEW_, _NW_, _of_, \
|
|
72
|
+
_PERCENTDOTSTAR_, _PLUS_, _PLUSMINUS_, _QUOTE1_, \
|
|
73
|
+
_QUOTE2_, _radians_, _S_, _SE_, _SPACE_, _SW_, _W_
|
|
73
74
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
74
75
|
# from pygeodesy.namedTuples import LatLon2Tuple # _MODS
|
|
75
76
|
# from pygeodesy.props import _throwarning # _MODS
|
|
@@ -84,12 +85,11 @@ except ImportError: # Python 3+
|
|
|
84
85
|
from string import ascii_letters as _LETTERS
|
|
85
86
|
|
|
86
87
|
__all__ = _ALL_LAZY.dms
|
|
87
|
-
__version__ = '24.
|
|
88
|
+
__version__ = '24.05.18'
|
|
88
89
|
|
|
89
90
|
_beyond_ = 'beyond'
|
|
90
91
|
_DDDMMSS_ = 'DDDMMSS'
|
|
91
92
|
_deg_min_ = 'deg+min'
|
|
92
|
-
_keyword_ = 'keyword'
|
|
93
93
|
_SDIGITS_ = '-0123456789+'
|
|
94
94
|
_sexagecimal_ = 'sexagecimal'
|
|
95
95
|
_SEXAGECIMUL = 1.e4 # sexagecimal C{D.MMSSss} into decimal C{DMMSS.ss}
|
pygeodesy/ecef.py
CHANGED
|
@@ -58,7 +58,7 @@ plane} as opposed to I{geocentric} (ECEF) ones.
|
|
|
58
58
|
'''
|
|
59
59
|
|
|
60
60
|
from pygeodesy.basics import copysign0, isscalar, issubclassof, neg, map1, \
|
|
61
|
-
_xinstanceof, _xsubclassof
|
|
61
|
+
_xinstanceof, _xsubclassof # _args_kwds_names
|
|
62
62
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS1, EPS2, EPS_2, INT0, PI, PI_2, \
|
|
63
63
|
_0_0, _0_0001, _0_01, _0_5, _1_0, _1_0_1T, _N_1_0, \
|
|
64
64
|
_2_0, _N_2_0, _3_0, _4_0, _6_0, _60_0, _90_0, _N_90_0, \
|
|
@@ -73,7 +73,7 @@ from pygeodesy.interns import NN, _a_, _C_, _datum_, _ellipsoid_, _f_, _height_,
|
|
|
73
73
|
_lat_, _lon_, _M_, _name_, _singular_, _SPACE_, \
|
|
74
74
|
_x_, _xyz_, _y_, _z_
|
|
75
75
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
76
|
-
from pygeodesy.named import _NamedBase, _NamedTuple, _Pass, _xnamed
|
|
76
|
+
from pygeodesy.named import _name__, _name1__, _NamedBase, _NamedTuple, _Pass, _xnamed
|
|
77
77
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, \
|
|
78
78
|
PhiLam2Tuple, Vector3Tuple, Vector4Tuple
|
|
79
79
|
from pygeodesy.props import deprecated_method, Property_RO, property_RO, property_doc_
|
|
@@ -86,7 +86,7 @@ from pygeodesy.utily import atan1, atan1d, atan2d, degrees90, degrees180, \
|
|
|
86
86
|
from math import atan2, cos, degrees, fabs, radians, sqrt
|
|
87
87
|
|
|
88
88
|
__all__ = _ALL_LAZY.ecef
|
|
89
|
-
__version__ = '24.05.
|
|
89
|
+
__version__ = '24.05.31'
|
|
90
90
|
|
|
91
91
|
_Ecef_ = 'Ecef'
|
|
92
92
|
_prolate_ = 'prolate'
|
|
@@ -108,7 +108,7 @@ class _EcefBase(_NamedBase):
|
|
|
108
108
|
_E = _EWGS84
|
|
109
109
|
_lon00 = INT0 # arbitrary, "polar" lon for LocalCartesian, Ltp
|
|
110
110
|
|
|
111
|
-
def __init__(self, a_ellipsoid=_EWGS84, f=None,
|
|
111
|
+
def __init__(self, a_ellipsoid=_EWGS84, f=None, lon00=INT0, **name):
|
|
112
112
|
'''New C{Ecef*} converter.
|
|
113
113
|
|
|
114
114
|
@arg a_ellipsoid: A (non-prolate) ellipsoid (L{Ellipsoid}, L{Ellipsoid2},
|
|
@@ -117,9 +117,9 @@ class _EcefBase(_NamedBase):
|
|
|
117
117
|
@kwarg f: C{None} or the ellipsoid flattening (C{scalar}), required
|
|
118
118
|
for C{scalar} B{C{a_ellipsoid}}, C{B{f}=0} represents a
|
|
119
119
|
sphere, negative B{C{f}} a prolate ellipsoid.
|
|
120
|
-
@kwarg name: Optional name (C{str}).
|
|
121
120
|
@kwarg lon00: An arbitrary, I{"polar"} longitude (C{degrees}), see the
|
|
122
|
-
|
|
121
|
+
C{reverse} method.
|
|
122
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
123
123
|
|
|
124
124
|
@raise EcefError: If B{C{a_ellipsoid}} not L{Ellipsoid}, L{Ellipsoid2},
|
|
125
125
|
L{Datum} or L{a_f2Tuple} or C{scalar} or B{C{f}} not
|
|
@@ -136,7 +136,7 @@ class _EcefBase(_NamedBase):
|
|
|
136
136
|
raise ValueError # _invalid_
|
|
137
137
|
|
|
138
138
|
if E not in (_EWGS84, _WGS84):
|
|
139
|
-
d = _ellipsoidal_datum(E, name
|
|
139
|
+
d = _ellipsoidal_datum(E, **name)
|
|
140
140
|
E = d.ellipsoid
|
|
141
141
|
if E.a < EPS or E.f > EPS1:
|
|
142
142
|
raise ValueError # _invalid_
|
|
@@ -209,9 +209,9 @@ class _EcefBase(_NamedBase):
|
|
|
209
209
|
m = self._Matrix(sa, ca, sb, cb) if M else None
|
|
210
210
|
return Ecef9Tuple(x * cb, x * sb, z, lat, lon, h,
|
|
211
211
|
0, m, self.datum,
|
|
212
|
-
name=
|
|
212
|
+
name=self._name__(name))
|
|
213
213
|
|
|
214
|
-
def forward(self, latlonh, lon=None, height=0, M=False, name
|
|
214
|
+
def forward(self, latlonh, lon=None, height=0, M=False, **name):
|
|
215
215
|
'''Convert from geodetic C{(lat, lon, height)} to geocentric C{(x, y, z)}.
|
|
216
216
|
|
|
217
217
|
@arg latlonh: Either a C{LatLon}, an L{Ecef9Tuple} or C{scalar}
|
|
@@ -221,7 +221,7 @@ class _EcefBase(_NamedBase):
|
|
|
221
221
|
@kwarg height: Optional height (C{meter}), vertically above (or below)
|
|
222
222
|
the surface of the ellipsoid.
|
|
223
223
|
@kwarg M: Optionally, return the rotation L{EcefMatrix} (C{bool}).
|
|
224
|
-
@kwarg name: Optional name (C{str}).
|
|
224
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
225
225
|
|
|
226
226
|
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)} with
|
|
227
227
|
geocentric C{(x, y, z)} coordinates for the given geodetic ones
|
|
@@ -235,10 +235,10 @@ class _EcefBase(_NamedBase):
|
|
|
235
235
|
@note: Use method C{.forward_} to specify C{lat} and C{lon} in C{radians}
|
|
236
236
|
and avoid double angle conversions.
|
|
237
237
|
'''
|
|
238
|
-
llhn = _llhn4(latlonh, lon, height, name
|
|
238
|
+
llhn = _llhn4(latlonh, lon, height, **name)
|
|
239
239
|
return self._forward(*llhn, M=M)
|
|
240
240
|
|
|
241
|
-
def forward_(self, phi, lam, height=0, M=False, name
|
|
241
|
+
def forward_(self, phi, lam, height=0, M=False, **name):
|
|
242
242
|
'''Like method C{.forward} except with geodetic lat- and longitude given
|
|
243
243
|
in I{radians}.
|
|
244
244
|
|
|
@@ -247,7 +247,7 @@ class _EcefBase(_NamedBase):
|
|
|
247
247
|
@kwarg height: Optional height (C{meter}), vertically above (or below)
|
|
248
248
|
the surface of the ellipsoid.
|
|
249
249
|
@kwarg M: Optionally, return the rotation L{EcefMatrix} (C{bool}).
|
|
250
|
-
@kwarg name: Optional name (C{str}).
|
|
250
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
251
251
|
|
|
252
252
|
@return: An L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)}
|
|
253
253
|
with C{lat} set to C{degrees90(B{phi})} and C{lon} to
|
|
@@ -255,8 +255,8 @@ class _EcefBase(_NamedBase):
|
|
|
255
255
|
|
|
256
256
|
@raise EcefError: If B{C{phi}} or B{C{lam}} invalid or not C{scalar}.
|
|
257
257
|
'''
|
|
258
|
-
try: # like function C{_llhn4}
|
|
259
|
-
plhn = Phi(phi), Lam(lam), Height(height), name
|
|
258
|
+
try: # like function C{_llhn4} below
|
|
259
|
+
plhn = Phi(phi), Lam(lam), Height(height), _name__(name)
|
|
260
260
|
except (TypeError, ValueError) as x:
|
|
261
261
|
raise EcefError(phi=phi, lam=lam, height=height, cause=x)
|
|
262
262
|
return self._forward(*plhn, M=M, _philam=True)
|
|
@@ -390,7 +390,7 @@ class EcefFarrell21(_EcefBase):
|
|
|
390
390
|
|
|
391
391
|
return Ecef9Tuple(x, y, z, lat, lon, h,
|
|
392
392
|
1, None, self.datum,
|
|
393
|
-
name=
|
|
393
|
+
name=self._name__(name))
|
|
394
394
|
|
|
395
395
|
|
|
396
396
|
class EcefFarrell22(_EcefBase):
|
|
@@ -451,7 +451,7 @@ class EcefFarrell22(_EcefBase):
|
|
|
451
451
|
|
|
452
452
|
return Ecef9Tuple(x, y, z, lat, lon, h,
|
|
453
453
|
1, None, self.datum,
|
|
454
|
-
name=
|
|
454
|
+
name=self._name__(name))
|
|
455
455
|
|
|
456
456
|
|
|
457
457
|
class EcefKarney(_EcefBase):
|
|
@@ -606,8 +606,7 @@ class EcefKarney(_EcefBase):
|
|
|
606
606
|
lon = self._polon(sb, cb, R, **name_lon00)
|
|
607
607
|
m = self._Matrix(sa, ca, sb, cb) if M else None
|
|
608
608
|
return Ecef9Tuple(x, y, z, atan1d(sa, ca), lon, h,
|
|
609
|
-
C, m, self.datum,
|
|
610
|
-
name=name or self.name)
|
|
609
|
+
C, m, self.datum, name=self._name__(name))
|
|
611
610
|
|
|
612
611
|
|
|
613
612
|
class EcefSudano(_EcefBase):
|
|
@@ -686,7 +685,7 @@ class EcefSudano(_EcefBase):
|
|
|
686
685
|
# h = (fabs(z) + R - E.a * cos(a + E.e21) * sa / ca) / (ca + sa)
|
|
687
686
|
return Ecef9Tuple(x, y, z, lat, lon, h,
|
|
688
687
|
i, None, self.datum, # C=i, M=None
|
|
689
|
-
iteration=i, name=
|
|
688
|
+
iteration=i, name=self._name__(name))
|
|
690
689
|
|
|
691
690
|
@property_doc_(''' the convergence tolerance (C{float}).''')
|
|
692
691
|
def tolerance(self):
|
|
@@ -782,7 +781,7 @@ class EcefVeness(_EcefBase):
|
|
|
782
781
|
lon = self._polon(y, x, p, **name_lon00)
|
|
783
782
|
return Ecef9Tuple(x, y, z, lat, lon, h,
|
|
784
783
|
C, None, self.datum, # M=None
|
|
785
|
-
name=
|
|
784
|
+
name=self._name__(name))
|
|
786
785
|
|
|
787
786
|
|
|
788
787
|
class EcefYou(_EcefBase):
|
|
@@ -862,7 +861,7 @@ class EcefYou(_EcefBase):
|
|
|
862
861
|
h = neg(h) # inside ellipsoid
|
|
863
862
|
return Ecef9Tuple(x, y, z, lat, lon, h,
|
|
864
863
|
1, None, self.datum, # C=1, M=None
|
|
865
|
-
name=
|
|
864
|
+
name=self._name__(name))
|
|
866
865
|
|
|
867
866
|
|
|
868
867
|
class EcefMatrix(_NamedTuple):
|
|
@@ -1160,22 +1159,24 @@ class Ecef9Tuple(_NamedTuple):
|
|
|
1160
1159
|
r = self.xyz
|
|
1161
1160
|
else:
|
|
1162
1161
|
_xsubclassof(self._CartesianBase, Cartesian=Cartesian)
|
|
1163
|
-
r = Cartesian(self, **
|
|
1162
|
+
r = Cartesian(self, **_name1__(Cartesian_kwds, _or_nameof=self))
|
|
1164
1163
|
return r
|
|
1165
1164
|
|
|
1166
|
-
def toDatum(self, datum2):
|
|
1165
|
+
def toDatum(self, datum2, **name):
|
|
1167
1166
|
'''Convert this C{Ecef9Tuple} to an other datum.
|
|
1168
1167
|
|
|
1169
1168
|
@arg datum2: Datum to convert I{to} (L{Datum}).
|
|
1169
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1170
1170
|
|
|
1171
1171
|
@return: The converted 9-Tuple (C{Ecef9Tuple}).
|
|
1172
1172
|
|
|
1173
1173
|
@raise TypeError: The B{C{datum2}} is not a L{Datum}.
|
|
1174
1174
|
'''
|
|
1175
|
+
n = _name__(name, _or_nameof=self)
|
|
1175
1176
|
if self.datum in (None, datum2): # PYCHOK _Names_
|
|
1176
|
-
r = self.copy()
|
|
1177
|
+
r = self.copy(name=n)
|
|
1177
1178
|
else:
|
|
1178
|
-
c = self._CartesianBase(self, datum=self.datum, name=
|
|
1179
|
+
c = self._CartesianBase(self, datum=self.datum, name=n) # PYCHOK _Names_
|
|
1179
1180
|
# c.toLatLon converts datum, x, y, z, lat, lon, etc.
|
|
1180
1181
|
# and returns another Ecef9Tuple iff LatLon is None
|
|
1181
1182
|
r = c.toLatLon(datum=datum2, LatLon=None)
|
|
@@ -1197,8 +1198,9 @@ class Ecef9Tuple(_NamedTuple):
|
|
|
1197
1198
|
@raise TypeError: Invalid B{C{LatLon}} or B{C{LatLon_kwds}}.
|
|
1198
1199
|
'''
|
|
1199
1200
|
lat, lon, D = self.lat, self.lon, self.datum # PYCHOK Ecef9Tuple
|
|
1200
|
-
kwds =
|
|
1201
|
-
|
|
1201
|
+
kwds = _name1__(LatLon_kwds, _or_nameof=self)
|
|
1202
|
+
kwds = _xkwds(kwds, height=self.height, datum=D) # PYCHOK Ecef9Tuple
|
|
1203
|
+
d = kwds.get(_datum_, LatLon)
|
|
1202
1204
|
if LatLon is None:
|
|
1203
1205
|
r = LatLon3Tuple(lat, lon, kwds[_height_], name=kwds[_name_])
|
|
1204
1206
|
if d is not None:
|
|
@@ -1242,7 +1244,7 @@ class Ecef9Tuple(_NamedTuple):
|
|
|
1242
1244
|
@see: Propertes C{xyz} and C{xyzh}
|
|
1243
1245
|
'''
|
|
1244
1246
|
return self.xyz if Vector is None else Vector(
|
|
1245
|
-
*self.xyz, **
|
|
1247
|
+
*self.xyz, **_name1__(Vector_kwds, _or_nameof=self)) # PYCHOK Ecef9Tuple
|
|
1246
1248
|
|
|
1247
1249
|
# def _T_x_M(self, T):
|
|
1248
1250
|
# '''(INTERNAL) Update M{self.M = T.multiply(self.M)}.
|
|
@@ -1272,25 +1274,23 @@ def _4Ecef(this, Ecef): # in .datums.Datum.ecef, .ellipsoids.Ellipsoid.ecef
|
|
|
1272
1274
|
return Ecef(this, name=this.name)
|
|
1273
1275
|
|
|
1274
1276
|
|
|
1275
|
-
def _llhn4(latlonh, lon, height, suffix=NN, Error=EcefError, name
|
|
1277
|
+
def _llhn4(latlonh, lon, height, suffix=NN, Error=EcefError, **name): # in .ltp
|
|
1276
1278
|
'''(INTERNAL) Get a C{(lat, lon, h, name)} 4-tuple.
|
|
1277
1279
|
'''
|
|
1278
1280
|
try:
|
|
1279
1281
|
lat, lon = latlonh.lat, latlonh.lon
|
|
1280
1282
|
h = _xattr(latlonh, height=_xattr(latlonh, h=height))
|
|
1281
|
-
n =
|
|
1283
|
+
n = _name__(name, _or_nameof=latlonh) # == latlonh._name__(name)
|
|
1282
1284
|
except AttributeError:
|
|
1283
|
-
lat, h, n = latlonh, height,
|
|
1284
|
-
|
|
1285
|
+
lat, h, n = latlonh, height, _name__(**name)
|
|
1285
1286
|
try:
|
|
1286
|
-
|
|
1287
|
+
return Lat(lat), Lon(lon), Height(h), n
|
|
1287
1288
|
except (TypeError, ValueError) as x:
|
|
1288
1289
|
t = _lat_, _lon_, _height_
|
|
1289
1290
|
if suffix:
|
|
1290
1291
|
t = (_ + suffix for _ in t)
|
|
1291
1292
|
d = dict(zip(t, (lat, lon, h)))
|
|
1292
1293
|
raise Error(cause=x, **d)
|
|
1293
|
-
return llhn
|
|
1294
1294
|
|
|
1295
1295
|
|
|
1296
1296
|
def _xEcef(Ecef): # PYCHOK .latlonBase
|
|
@@ -1302,23 +1302,23 @@ def _xEcef(Ecef): # PYCHOK .latlonBase
|
|
|
1302
1302
|
|
|
1303
1303
|
|
|
1304
1304
|
# kwd lon00 unused but will throw a TypeError if misspelled, etc.
|
|
1305
|
-
def _xyzn4(xyz, y, z, Types, Error=EcefError,
|
|
1306
|
-
_xyz_y_z_names=_xyz_y_z,
|
|
1305
|
+
def _xyzn4(xyz, y, z, Types, Error=EcefError, lon00=0, # PYCHOK unused
|
|
1306
|
+
_xyz_y_z_names=_xyz_y_z, **name): # in .ltp
|
|
1307
1307
|
'''(INTERNAL) Get an C{(x, y, z, name)} 4-tuple.
|
|
1308
1308
|
'''
|
|
1309
1309
|
try:
|
|
1310
|
+
n = _name__(name, _or_nameof=xyz) # == xyz._name__(name)
|
|
1310
1311
|
try:
|
|
1311
|
-
t = xyz.x, xyz.y, xyz.z,
|
|
1312
|
+
t = xyz.x, xyz.y, xyz.z, n
|
|
1312
1313
|
if not isinstance(xyz, Types):
|
|
1313
1314
|
raise _TypesError(_xyz_y_z_names[0], xyz, *Types)
|
|
1314
1315
|
except AttributeError:
|
|
1315
|
-
t = map1(float, xyz, y, z) + (
|
|
1316
|
-
|
|
1316
|
+
t = map1(float, xyz, y, z) + (n,)
|
|
1317
1317
|
except (TypeError, ValueError) as x:
|
|
1318
1318
|
d = dict(zip(_xyz_y_z_names, (xyz, y, z)))
|
|
1319
1319
|
raise Error(cause=x, **d)
|
|
1320
1320
|
return t
|
|
1321
|
-
# assert _xyz_y_z ==
|
|
1321
|
+
# assert _xyz_y_z == _args_kwds_names(_xyzn4)[:3]
|
|
1322
1322
|
|
|
1323
1323
|
|
|
1324
1324
|
_Ecefs = (EcefKarney, EcefSudano, EcefVeness, EcefYou,
|