pygeodesy 24.5.8__py2.py3-none-any.whl → 24.5.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.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
- PyGeodesy-24.5.24.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +16 -12
- pygeodesy/__main__.py +9 -10
- pygeodesy/albers.py +42 -42
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +7 -10
- pygeodesy/auxilats/auxAngle.py +32 -31
- pygeodesy/auxilats/auxLat.py +81 -51
- pygeodesy/azimuthal.py +123 -124
- pygeodesy/basics.py +165 -176
- pygeodesy/booleans.py +14 -15
- pygeodesy/cartesianBase.py +25 -23
- pygeodesy/clipy.py +3 -3
- pygeodesy/constants.py +8 -6
- pygeodesy/css.py +50 -42
- pygeodesy/datums.py +50 -48
- pygeodesy/dms.py +6 -6
- pygeodesy/ecef.py +27 -27
- pygeodesy/elevations.py +2 -2
- pygeodesy/ellipsoidalBase.py +28 -27
- pygeodesy/ellipsoidalBaseDI.py +8 -7
- pygeodesy/ellipsoidalNvector.py +11 -12
- pygeodesy/ellipsoids.py +41 -35
- pygeodesy/elliptic.py +12 -10
- pygeodesy/epsg.py +4 -3
- pygeodesy/errors.py +35 -13
- pygeodesy/etm.py +62 -53
- pygeodesy/fmath.py +48 -41
- pygeodesy/formy.py +93 -65
- pygeodesy/frechet.py +117 -102
- pygeodesy/fstats.py +52 -46
- pygeodesy/fsums.py +169 -145
- pygeodesy/gars.py +10 -9
- pygeodesy/geodesicw.py +32 -30
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +4 -4
- pygeodesy/geodesicx/gx.py +40 -32
- pygeodesy/geodesicx/gxarea.py +15 -12
- pygeodesy/geodesicx/gxbases.py +3 -4
- pygeodesy/geodesicx/gxline.py +6 -8
- pygeodesy/geodsolve.py +28 -26
- pygeodesy/geohash.py +47 -44
- pygeodesy/geoids.py +37 -35
- pygeodesy/hausdorff.py +112 -99
- pygeodesy/heights.py +136 -129
- pygeodesy/internals.py +576 -0
- pygeodesy/interns.py +6 -207
- pygeodesy/iters.py +22 -19
- pygeodesy/karney.py +18 -15
- pygeodesy/ktm.py +31 -24
- pygeodesy/latlonBase.py +12 -11
- pygeodesy/lazily.py +140 -218
- pygeodesy/lcc.py +24 -25
- pygeodesy/ltp.py +83 -71
- pygeodesy/ltpTuples.py +7 -5
- pygeodesy/mgrs.py +5 -4
- pygeodesy/named.py +136 -49
- pygeodesy/namedTuples.py +33 -25
- pygeodesy/nvectorBase.py +10 -9
- pygeodesy/osgr.py +14 -12
- pygeodesy/points.py +13 -13
- pygeodesy/props.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/bases.py +3 -2
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +8 -7
- pygeodesy/sphericalTrigonometry.py +5 -5
- pygeodesy/streprs.py +8 -7
- pygeodesy/trf.py +8 -8
- pygeodesy/triaxials.py +67 -63
- pygeodesy/units.py +48 -50
- pygeodesy/unitsBase.py +24 -11
- pygeodesy/ups.py +7 -6
- pygeodesy/utily.py +4 -4
- pygeodesy/utm.py +53 -52
- pygeodesy/utmupsBase.py +11 -8
- pygeodesy/vector2d.py +6 -7
- pygeodesy/vector3d.py +16 -17
- pygeodesy/vector3dBase.py +5 -5
- PyGeodesy-24.5.8.dist-info/RECORD +0 -115
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/datums.py
CHANGED
|
@@ -67,23 +67,24 @@ datum, q.v. U{"A Guide to Coordinate Systems in Great Britain", Section 6
|
|
|
67
67
|
# make sure int/int division yields float quotient, see .basics
|
|
68
68
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
69
69
|
|
|
70
|
-
from pygeodesy.basics import islistuple, map2, neg,
|
|
70
|
+
from pygeodesy.basics import islistuple, map2, neg, _xinstanceof, _zip
|
|
71
71
|
from pygeodesy.constants import R_M, _float as _F, _0_0, _1_0, _2_0, _8_0, _3600_0
|
|
72
72
|
# from pygeodesy.ellipsoidalBase import CartesianEllipsoidalBase as _CEB, \
|
|
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
|
|
78
|
+
from pygeodesy.internals import _passarg, _under
|
|
79
79
|
from pygeodesy.interns import NN, _a_, _Airy1830_, _AiryModified_, _BAR_, _Bessel1841_, \
|
|
80
|
-
_Clarke1866_, _Clarke1880IGN_, _COMMASPACE_, _DOT_, \
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
_Clarke1866_, _Clarke1880IGN_, _COMMASPACE_, _DOT_, _earth_, \
|
|
81
|
+
_ellipsoid_, _ellipsoidal_, _GRS80_, _Intl1924_, _MINUS_, \
|
|
82
|
+
_Krassovski1940_, _Krassowsky1940_, _NAD27_, _NAD83_, _s_, \
|
|
83
|
+
_PLUS_, _Sphere_, _spherical_, _transform_, _UNDER_, \
|
|
84
|
+
_WGS72_, _WGS84_
|
|
85
85
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
86
|
-
from pygeodesy.named import
|
|
86
|
+
from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _name2__, _NamedEnum, \
|
|
87
|
+
_NamedEnumItem
|
|
87
88
|
# from pygeodesy.namedTuples import Vector3Tuple # from .ellipsoids
|
|
88
89
|
from pygeodesy.props import Property_RO, property_RO
|
|
89
90
|
# from pygeodesy.streprs import Fmt # from .fmath
|
|
@@ -93,7 +94,7 @@ from pygeodesy.units import _isRadius, Radius_, radians
|
|
|
93
94
|
# import operator as _operator # from .fmath
|
|
94
95
|
|
|
95
96
|
__all__ = _ALL_LAZY.datums
|
|
96
|
-
__version__ = '24.
|
|
97
|
+
__version__ = '24.05.21'
|
|
97
98
|
|
|
98
99
|
_a_ellipsoid_ = _UNDER_(_a_, _ellipsoid_)
|
|
99
100
|
_BD72_ = 'BD72'
|
|
@@ -203,15 +204,15 @@ class Transform(_NamedEnumItem):
|
|
|
203
204
|
def __neg__(self):
|
|
204
205
|
return self.inverse()
|
|
205
206
|
|
|
206
|
-
def inverse(self, name
|
|
207
|
+
def inverse(self, **name):
|
|
207
208
|
'''Return the inverse of this transform.
|
|
208
209
|
|
|
209
210
|
@kwarg name: Optional, unique name (C{str}).
|
|
210
211
|
|
|
211
212
|
@return: Inverse (L{Transform}), unregistered.
|
|
212
213
|
'''
|
|
213
|
-
r =
|
|
214
|
-
n = name or _negastr(self.name)
|
|
214
|
+
r = type(self)(**dict(self.items(inverse=True)))
|
|
215
|
+
n = _name__(**name) or _negastr(self.name)
|
|
215
216
|
if n:
|
|
216
217
|
r.name = n # unregistered
|
|
217
218
|
return r
|
|
@@ -247,16 +248,17 @@ class Transform(_NamedEnumItem):
|
|
|
247
248
|
self.s = s = (s1 - _1_0) / _S1_S
|
|
248
249
|
return s
|
|
249
250
|
|
|
250
|
-
def toStr(self, prec=5, fmt=Fmt.g, name
|
|
251
|
+
def toStr(self, prec=5, fmt=Fmt.g, **name): # PYCHOK expected
|
|
251
252
|
'''Return this transform as a string.
|
|
252
253
|
|
|
253
254
|
@kwarg prec: Number of (decimal) digits, unstripped (C{int}).
|
|
254
255
|
@kwarg fmt: Optional C{float} format (C{letter}).
|
|
255
|
-
@kwarg name:
|
|
256
|
-
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.
|
|
257
258
|
|
|
258
259
|
@return: Transform attributes (C{str}).
|
|
259
260
|
'''
|
|
261
|
+
name, _ = _name2__(**name) # name=None
|
|
260
262
|
return self._instr(name, prec, *_Names11, fmt=fmt)
|
|
261
263
|
|
|
262
264
|
def transform(self, x, y, z, inverse=False, **Vector_and_kwds):
|
|
@@ -377,12 +379,12 @@ class Datum(_NamedEnumItem):
|
|
|
377
379
|
_ellipsoid = Ellipsoids.WGS84 # default ellipsoid (L{Ellipsoid}, L{Ellipsoid2})
|
|
378
380
|
_transform = Transforms.WGS84 # default transform (L{Transform})
|
|
379
381
|
|
|
380
|
-
def __init__(self, ellipsoid, transform=None, name
|
|
382
|
+
def __init__(self, ellipsoid, transform=None, **name):
|
|
381
383
|
'''New L{Datum}.
|
|
382
384
|
|
|
383
385
|
@arg ellipsoid: The ellipsoid (L{Ellipsoid} or L{Ellipsoid2}).
|
|
384
386
|
@kwarg transform: Optional transform (L{Transform}).
|
|
385
|
-
@kwarg name: Optional, unique name (C{str}).
|
|
387
|
+
@kwarg name: Optional, unique C{B{name}=NN} (C{str}).
|
|
386
388
|
|
|
387
389
|
@raise NameError: Datum with that B{C{name}} already exists.
|
|
388
390
|
|
|
@@ -396,7 +398,8 @@ class Datum(_NamedEnumItem):
|
|
|
396
398
|
self._transform = transform or Datum._transform
|
|
397
399
|
_xinstanceof(Transform, transform=self.transform)
|
|
398
400
|
|
|
399
|
-
self._register(Datums, name or self.transform.name
|
|
401
|
+
self._register(Datums, _name__(name) or self.transform.name
|
|
402
|
+
or self.ellipsoid.name)
|
|
400
403
|
|
|
401
404
|
def __eq__(self, other):
|
|
402
405
|
'''Compare this and an other datum.
|
|
@@ -473,15 +476,16 @@ class Datum(_NamedEnumItem):
|
|
|
473
476
|
'''
|
|
474
477
|
return self.ellipsoid.isSpherical
|
|
475
478
|
|
|
476
|
-
def toStr(self, sep=_COMMASPACE_, name
|
|
479
|
+
def toStr(self, sep=_COMMASPACE_, **name): # PYCHOK expected
|
|
477
480
|
'''Return this datum as a string.
|
|
478
481
|
|
|
479
482
|
@kwarg sep: Separator to join (C{str}).
|
|
480
|
-
@kwarg name:
|
|
481
|
-
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.
|
|
482
485
|
|
|
483
486
|
@return: Datum attributes (C{str}).
|
|
484
487
|
'''
|
|
488
|
+
name, _ = _name2__(**name) # name=None
|
|
485
489
|
t = [] if name is None else \
|
|
486
490
|
[Fmt.EQUAL(name=repr(name or self.named))]
|
|
487
491
|
for a in (_ellipsoid_, _transform_):
|
|
@@ -496,7 +500,7 @@ class Datum(_NamedEnumItem):
|
|
|
496
500
|
return self._transform
|
|
497
501
|
|
|
498
502
|
|
|
499
|
-
def _earth_datum(inst, a_earth, f=None,
|
|
503
|
+
def _earth_datum(inst, a_earth, f=None, raiser=_a_ellipsoid_, **name): # in .karney, .trf, ...
|
|
500
504
|
'''(INTERNAL) Set C{inst._datum} from C{(B{a_..}, B{f})} or C{B{.._ellipsoid}}
|
|
501
505
|
(L{Ellipsoid}, L{Ellipsoid2}, L{Datum}, C{a_f2Tuple} or C{scalar} earth radius).
|
|
502
506
|
|
|
@@ -519,12 +523,12 @@ def _earth_datum(inst, a_earth, f=None, name=NN, raiser=_a_ellipsoid_): # in .k
|
|
|
519
523
|
inst._datum = D
|
|
520
524
|
|
|
521
525
|
|
|
522
|
-
def _earth_ellipsoid(earth,
|
|
526
|
+
def _earth_ellipsoid(earth, **name_raiser):
|
|
523
527
|
'''(INTERAL) Return the ellipsoid for the given C{earth} model.
|
|
524
528
|
'''
|
|
525
529
|
return Ellipsoids.Sphere if earth is R_M else (
|
|
526
530
|
_EWGS84 if earth is _EWGS84 or earth is _WGS84 else
|
|
527
|
-
_spherical_datum(earth,
|
|
531
|
+
_spherical_datum(earth, **name_raiser).ellipsoid)
|
|
528
532
|
|
|
529
533
|
|
|
530
534
|
def _ED2(radius, name):
|
|
@@ -533,13 +537,13 @@ def _ED2(radius, name):
|
|
|
533
537
|
D = Datums.Sphere
|
|
534
538
|
E = D.ellipsoid
|
|
535
539
|
if name or radius != E.a: # != E.b
|
|
536
|
-
n = _under(name)
|
|
540
|
+
n = _under(_name__(name, _or_nameof=D))
|
|
537
541
|
E = Ellipsoid(radius, radius, name=n)
|
|
538
542
|
D = Datum(E, transform=Transforms.Identity, name=n)
|
|
539
543
|
return E, D
|
|
540
544
|
|
|
541
545
|
|
|
542
|
-
def _ellipsoidal_datum(earth, Error=TypeError,
|
|
546
|
+
def _ellipsoidal_datum(earth, Error=TypeError, raiser=NN, **name):
|
|
543
547
|
'''(INTERNAL) Create a L{Datum} from an L{Ellipsoid} or L{Ellipsoid2},
|
|
544
548
|
C{a_f2Tuple}, 2-tuple or 2-list B{C{earth}} model.
|
|
545
549
|
|
|
@@ -562,29 +566,25 @@ def _ellipsoidal_datum(earth, Error=TypeError, name=NN, raiser=NN):
|
|
|
562
566
|
def _EnD3(earth, name):
|
|
563
567
|
'''(INTERNAL) Helper for C{_earth_datum} and C{_ellipsoidal_datum}.
|
|
564
568
|
'''
|
|
565
|
-
D = None
|
|
569
|
+
D, n = None, _under(_name__(name, _or_nameof=earth))
|
|
566
570
|
if isinstance(earth, (Ellipsoid, Ellipsoid2)):
|
|
567
|
-
E =
|
|
568
|
-
n = _under(name or E.name)
|
|
571
|
+
E = earth
|
|
569
572
|
elif isinstance(earth, Datum):
|
|
570
|
-
E =
|
|
571
|
-
|
|
572
|
-
D = earth
|
|
573
|
+
E = earth.ellipsoid
|
|
574
|
+
D = earth
|
|
573
575
|
elif _isRadius(earth):
|
|
574
|
-
E, D = _ED2(Radius_(earth),
|
|
575
|
-
n =
|
|
576
|
+
E, D = _ED2(Radius_(earth), n)
|
|
577
|
+
n = E.name
|
|
576
578
|
elif isinstance(earth, a_f2Tuple):
|
|
577
|
-
|
|
578
|
-
E = earth.ellipsoid(name=n)
|
|
579
|
+
E = earth.ellipsoid(name=n)
|
|
579
580
|
elif islistuple(earth, minum=2):
|
|
580
|
-
E =
|
|
581
|
+
E = Ellipsoids.Sphere
|
|
581
582
|
a, f = earth[:2]
|
|
582
583
|
if f or a != E.a: # != E.b
|
|
583
|
-
|
|
584
|
-
E = Ellipsoid(a, f=f, name=n)
|
|
584
|
+
E = Ellipsoid(a, f=f, name=n)
|
|
585
585
|
else:
|
|
586
|
-
n =
|
|
587
|
-
D =
|
|
586
|
+
n = E.name
|
|
587
|
+
D = Datums.Sphere
|
|
588
588
|
else:
|
|
589
589
|
E, n = None, NN
|
|
590
590
|
return E, n, D
|
|
@@ -623,16 +623,18 @@ def _negastr(name): # in .trf
|
|
|
623
623
|
return n.lstrip(p) if n.startswith(p) else NN(m, n)
|
|
624
624
|
|
|
625
625
|
|
|
626
|
-
def _spherical_datum(earth, Error=TypeError,
|
|
626
|
+
def _spherical_datum(earth, Error=TypeError, raiser=NN, **name):
|
|
627
627
|
'''(INTERNAL) Create a L{Datum} from an L{Ellipsoid}, L{Ellipsoid2},
|
|
628
628
|
C{a_f2Tuple}, 2-tuple, 2-list B{C{earth}} model or C{scalar} radius.
|
|
629
629
|
|
|
630
630
|
@kwarg raiser: If not C{NN}, raise an B{C{Error}} if not spherical.
|
|
631
631
|
'''
|
|
632
|
-
if
|
|
632
|
+
if isinstance(earth, Datum):
|
|
633
|
+
D = earth
|
|
634
|
+
elif _isRadius(earth):
|
|
633
635
|
_, D = _ED2(Radius_(earth, Error=Error), name)
|
|
634
636
|
else:
|
|
635
|
-
D = _ellipsoidal_datum(earth, Error=Error, name
|
|
637
|
+
D = _ellipsoidal_datum(earth, Error=Error, **name)
|
|
636
638
|
if raiser and not D.isSpherical:
|
|
637
639
|
raise _IsnotError(_spherical_, Error=Error, **{raiser: earth})
|
|
638
640
|
return D
|
|
@@ -642,11 +644,11 @@ class Datums(_NamedEnum):
|
|
|
642
644
|
'''(INTERNAL) L{Datum} registry, I{must} be a sub-class
|
|
643
645
|
to accommodate the L{_LazyNamedEnumItem} properties.
|
|
644
646
|
'''
|
|
645
|
-
def _Lazy(self, ellipsoid_name, transform_name, name
|
|
647
|
+
def _Lazy(self, ellipsoid_name, transform_name, **name):
|
|
646
648
|
'''(INTERNAL) Instantiate the L{Datum}.
|
|
647
649
|
'''
|
|
648
650
|
return Datum(Ellipsoids.get(ellipsoid_name),
|
|
649
|
-
Transforms.get(transform_name), name
|
|
651
|
+
Transforms.get(transform_name), **name)
|
|
650
652
|
|
|
651
653
|
Datums = Datums(Datum) # PYCHOK singleton
|
|
652
654
|
'''Some pre-defined L{Datum}s, all I{lazily} instantiated.'''
|
|
@@ -722,7 +724,7 @@ assert _WGS84.ellipsoid is _EWGS84
|
|
|
722
724
|
if __name__ == '__main__':
|
|
723
725
|
|
|
724
726
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
725
|
-
from pygeodesy
|
|
727
|
+
from pygeodesy import printf
|
|
726
728
|
|
|
727
729
|
# __doc__ of this file, force all into registery
|
|
728
730
|
for r in (Datums, Transforms):
|
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
|
@@ -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__, _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.21'
|
|
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_
|
|
@@ -211,7 +211,7 @@ class _EcefBase(_NamedBase):
|
|
|
211
211
|
0, m, self.datum,
|
|
212
212
|
name=name or self.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)
|
|
@@ -646,7 +646,7 @@ class EcefSudano(_EcefBase):
|
|
|
646
646
|
|
|
647
647
|
_a = fabs
|
|
648
648
|
lat = atan1d(z, R * E.e21)
|
|
649
|
-
sa, ca = sincos2d(
|
|
649
|
+
sa, ca = sincos2d(_a(lat))
|
|
650
650
|
# Sudano's Eq (A-6) and (A-7) refactored/reduced,
|
|
651
651
|
# replacing Rn from Eq (A-4) with n = E.a / ca:
|
|
652
652
|
# N = ca**2 * ((z + E.e2 * n * sa) * ca - R * sa)
|
|
@@ -656,17 +656,18 @@ class EcefSudano(_EcefBase):
|
|
|
656
656
|
# = ca**2 * (E.e2 * E.a / E.e2s2(sa) - R / ca**2)
|
|
657
657
|
# N / D = (z * ca + (E.e2 * E.a - R) * sa) /
|
|
658
658
|
# (E.e2 * E.a / E.e2s2(sa) - R / ca**2)
|
|
659
|
+
_E = EPS_2
|
|
659
660
|
tol = self.tolerance
|
|
660
661
|
_S2 = Fsum(sa).fsum2f_
|
|
661
662
|
_rt = sqrt
|
|
662
663
|
for i in range(1, _TRIPS):
|
|
663
664
|
ca2 = _1_0 - sa**2
|
|
664
|
-
if ca2 <
|
|
665
|
+
if ca2 < _E: # PYCHOK no cover
|
|
665
666
|
ca = _0_0
|
|
666
667
|
break
|
|
667
668
|
ca = _rt(ca2)
|
|
668
669
|
r = e / E.e2s2(sa) - R / ca2
|
|
669
|
-
if _a(r) <
|
|
670
|
+
if _a(r) < _E:
|
|
670
671
|
break
|
|
671
672
|
lat = None
|
|
672
673
|
sa, r = _S2(-z * ca / r, -d * sa / r)
|
|
@@ -1271,25 +1272,24 @@ def _4Ecef(this, Ecef): # in .datums.Datum.ecef, .ellipsoids.Ellipsoid.ecef
|
|
|
1271
1272
|
return Ecef(this, name=this.name)
|
|
1272
1273
|
|
|
1273
1274
|
|
|
1274
|
-
def _llhn4(latlonh, lon, height, suffix=NN, Error=EcefError, name
|
|
1275
|
+
def _llhn4(latlonh, lon, height, suffix=NN, Error=EcefError, **name): # in .ltp
|
|
1275
1276
|
'''(INTERNAL) Get a C{(lat, lon, h, name)} 4-tuple.
|
|
1276
1277
|
'''
|
|
1277
1278
|
try:
|
|
1278
1279
|
lat, lon = latlonh.lat, latlonh.lon
|
|
1279
1280
|
h = _xattr(latlonh, height=_xattr(latlonh, h=height))
|
|
1280
|
-
n =
|
|
1281
|
+
n = _name__(name, _or_nameof=latlonh) # == latlonh._name__(name)
|
|
1281
1282
|
except AttributeError:
|
|
1282
|
-
lat, h, n = latlonh, height,
|
|
1283
|
+
lat, h, n = latlonh, height, _name__(**name)
|
|
1283
1284
|
|
|
1284
1285
|
try:
|
|
1285
|
-
|
|
1286
|
+
return Lat(lat), Lon(lon), Height(h), n
|
|
1286
1287
|
except (TypeError, ValueError) as x:
|
|
1287
1288
|
t = _lat_, _lon_, _height_
|
|
1288
1289
|
if suffix:
|
|
1289
1290
|
t = (_ + suffix for _ in t)
|
|
1290
1291
|
d = dict(zip(t, (lat, lon, h)))
|
|
1291
1292
|
raise Error(cause=x, **d)
|
|
1292
|
-
return llhn
|
|
1293
1293
|
|
|
1294
1294
|
|
|
1295
1295
|
def _xEcef(Ecef): # PYCHOK .latlonBase
|
|
@@ -1301,22 +1301,22 @@ def _xEcef(Ecef): # PYCHOK .latlonBase
|
|
|
1301
1301
|
|
|
1302
1302
|
|
|
1303
1303
|
# kwd lon00 unused but will throw a TypeError if misspelled, etc.
|
|
1304
|
-
def _xyzn4(xyz, y, z, Types, Error=EcefError,
|
|
1305
|
-
_xyz_y_z_names=_xyz_y_z,
|
|
1304
|
+
def _xyzn4(xyz, y, z, Types, Error=EcefError, lon00=0, # PYCHOK unused
|
|
1305
|
+
_xyz_y_z_names=_xyz_y_z, **name): # in .ltp
|
|
1306
1306
|
'''(INTERNAL) Get an C{(x, y, z, name)} 4-tuple.
|
|
1307
1307
|
'''
|
|
1308
1308
|
try:
|
|
1309
|
+
n = _name__(name, _or_nameof=xyz) # == xyz._name__(name)
|
|
1309
1310
|
try:
|
|
1310
|
-
t = xyz.x, xyz.y, xyz.z,
|
|
1311
|
+
t = xyz.x, xyz.y, xyz.z, n
|
|
1311
1312
|
if not isinstance(xyz, Types):
|
|
1312
1313
|
raise _TypesError(_xyz_y_z_names[0], xyz, *Types)
|
|
1313
1314
|
except AttributeError:
|
|
1314
|
-
t = map1(float, xyz, y, z) + (
|
|
1315
|
-
|
|
1315
|
+
t = map1(float, xyz, y, z) + (n,)
|
|
1316
|
+
return t
|
|
1316
1317
|
except (TypeError, ValueError) as x:
|
|
1317
1318
|
d = dict(zip(_xyz_y_z_names, (xyz, y, z)))
|
|
1318
1319
|
raise Error(cause=x, **d)
|
|
1319
|
-
return t
|
|
1320
1320
|
# assert _xyz_y_z == _MODS.basics._args_kwds_names(_xyzn4)[:3]
|
|
1321
1321
|
|
|
1322
1322
|
|
pygeodesy/elevations.py
CHANGED
|
@@ -34,7 +34,7 @@ from pygeodesy.units import Lat, Lon, Meter, Scalar, Str
|
|
|
34
34
|
# from math import fabs # from .karney
|
|
35
35
|
|
|
36
36
|
__all__ = _ALL_LAZY.elevations
|
|
37
|
-
__version__ = '
|
|
37
|
+
__version__ = '24.05.13'
|
|
38
38
|
|
|
39
39
|
try:
|
|
40
40
|
from urllib2 import urlopen # quote, urlcleanup
|
|
@@ -245,7 +245,7 @@ def geoidHeight2(lat, lon, model=0, timeout=2.0):
|
|
|
245
245
|
|
|
246
246
|
if __name__ == '__main__':
|
|
247
247
|
|
|
248
|
-
from pygeodesy
|
|
248
|
+
from pygeodesy import printf
|
|
249
249
|
# <https://WikiPedia.org/wiki/Mount_Diablo>
|
|
250
250
|
for f in (elevation2, # (1173.79, '3DEP 1/3 arc-second')
|
|
251
251
|
geoidHeight2): # (-31.699, u'GEOID12B')
|