pygeodesy 25.4.8__py2.py3-none-any.whl → 25.5.5__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/__init__.py +36 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +9 -9
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +8 -6
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +5 -3
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +32 -18
- pygeodesy/booleans.py +18 -16
- pygeodesy/cartesianBase.py +26 -24
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +22 -29
- pygeodesy/ecefLocals.py +186 -0
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +186 -164
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +7 -7
- pygeodesy/fmath.py +30 -14
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +79 -78
- pygeodesy/gars.py +4 -3
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +11 -9
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +5 -5
- pygeodesy/geoids.py +34 -31
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +28 -44
- pygeodesy/interns.py +10 -7
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +68 -62
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +20 -21
- pygeodesy/lazily.py +104 -78
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +56 -58
- pygeodesy/ltpTuples.py +35 -36
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +48 -177
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +83 -80
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +7 -7
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +110 -18
- pygeodesy/vector2d.py +20 -13
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/METADATA +30 -25
- pygeodesy-25.5.5.dist-info/RECORD +119 -0
- pygeodesy-25.4.8.dist-info/RECORD +0 -118
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/WHEEL +0 -0
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/top_level.txt +0 -0
pygeodesy/datums.py
CHANGED
|
@@ -67,7 +67,7 @@ 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, _xinstanceof, _zip
|
|
70
|
+
from pygeodesy.basics import _isin, 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
|
|
@@ -77,10 +77,10 @@ from pygeodesy.errors import _IsnotError, _TypeError, _xellipsoidall, _xkwds, _x
|
|
|
77
77
|
from pygeodesy.fmath import fdot, fmean, Fmt, _operator
|
|
78
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
|
-
_ellipsoid_, _ellipsoidal_, _GRS80_, _Intl1924_,
|
|
82
|
-
_Krassovski1940_, _Krassowsky1940_, _NAD27_, _NAD83_,
|
|
83
|
-
_PLUS_, _Sphere_, _spherical_, _transform_, _UNDER_, \
|
|
80
|
+
_Clarke1866_, _Clarke1880IGN_, _COMMASPACE_, _DMAIN_,_DOT_, \
|
|
81
|
+
_earth_, _ellipsoid_, _ellipsoidal_, _GRS80_, _Intl1924_, \
|
|
82
|
+
_MINUS_, _Krassovski1940_, _Krassowsky1940_, _NAD27_, _NAD83_, \
|
|
83
|
+
_s_, _PLUS_, _Sphere_, _spherical_, _transform_, _UNDER_, \
|
|
84
84
|
_WGS72_, _WGS84_
|
|
85
85
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
86
86
|
from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _name2__, _NamedEnum, \
|
|
@@ -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__ = '
|
|
97
|
+
__version__ = '25.04.14'
|
|
98
98
|
|
|
99
99
|
_a_ellipsoid_ = _UNDER_(_a_, _ellipsoid_)
|
|
100
100
|
_BD72_ = 'BD72'
|
|
@@ -510,7 +510,7 @@ def _earth_datum(inst, a_earth, f=None, raiser=_a_ellipsoid_, **name): # in .ka
|
|
|
510
510
|
E, n, D = _EnD3((a_earth, f), name)
|
|
511
511
|
if raiser and not E:
|
|
512
512
|
raise _TypeError(f=f, **{raiser: a_earth})
|
|
513
|
-
elif a_earth
|
|
513
|
+
elif _isin(a_earth, None, _EWGS84, _WGS84) and inst._datum is _WGS84:
|
|
514
514
|
return
|
|
515
515
|
elif isinstance(a_earth, Datum):
|
|
516
516
|
E, n, D = None, NN, a_earth
|
|
@@ -721,7 +721,7 @@ _WGS84 = Datums.WGS84
|
|
|
721
721
|
assert _WGS84.ellipsoid is _EWGS84
|
|
722
722
|
# assert _WGS84.transform.isunity
|
|
723
723
|
|
|
724
|
-
if __name__ ==
|
|
724
|
+
if __name__ == _DMAIN_:
|
|
725
725
|
|
|
726
726
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
727
727
|
from pygeodesy import printf
|
pygeodesy/deprecated/bases.py
CHANGED
|
@@ -9,11 +9,11 @@ from pygeodesy.latlonBase import LatLonBase as _LatLonBase
|
|
|
9
9
|
from pygeodesy.lazily import _ALL_DEPRECATED
|
|
10
10
|
|
|
11
11
|
__all__ = _ALL_DEPRECATED.deprecated_bases
|
|
12
|
-
__version__ = '
|
|
12
|
+
__version__ = '25.04.09'
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class LatLonHeightBase(_LatLonBase): # PYCHOK no cover
|
|
16
|
-
'''
|
|
16
|
+
'''DEPRECATED on 2021.02.10, use (INTERNAL) class L{pygeodesy.latlonBase.LatLonBase}.'''
|
|
17
17
|
pass
|
|
18
18
|
|
|
19
19
|
|
pygeodesy/deprecated/classes.py
CHANGED
|
@@ -22,7 +22,7 @@ from pygeodesy.trf import TRFXform7Tuple as _TRFXform7Tuple
|
|
|
22
22
|
from pygeodesy.units import Bearing, Int, Lamd, Lat, Lon, Meter, Phid
|
|
23
23
|
|
|
24
24
|
__all__ = _ALL_DEPRECATED.deprecated_classes
|
|
25
|
-
__version__ = '
|
|
25
|
+
__version__ = '25.04.11'
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class _Deprecated_NamedTuple(_NamedTuple):
|
|
@@ -349,7 +349,7 @@ class UtmUps4Tuple(_Deprecated_NamedTuple): # PYCHOK no cover
|
|
|
349
349
|
|
|
350
350
|
|
|
351
351
|
class XDist(ADict):
|
|
352
|
-
'''DEPRECATED on 2024.07.02, use class L{
|
|
352
|
+
'''DEPRECATED on 2024.07.02, use class L{ADict}.'''
|
|
353
353
|
def __init__(self, *args, **kwds): # PYCHOK no cover
|
|
354
354
|
deprecated_class(self.__class__)
|
|
355
355
|
ADict.__init__(self, *args, **kwds)
|
|
@@ -9,21 +9,21 @@ from pygeodesy.lazily import _ALL_DEPRECATED
|
|
|
9
9
|
from pygeodesy.units import Float, Int, Str
|
|
10
10
|
|
|
11
11
|
__all__ = _ALL_DEPRECATED.deprecated_consterns
|
|
12
|
-
__version__ = '
|
|
12
|
+
__version__ = '25.04.09'
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class _Deprecated_Float(Float):
|
|
16
|
-
'''DEPRECATED on 2023.09.12, don't use.'''
|
|
16
|
+
'''DEPRECATED on 2023.09.12, I{don't use}.'''
|
|
17
17
|
pass
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class _Deprecated_Int(Int):
|
|
21
|
-
'''DEPRECATED on 2023.09.12, don't use.'''
|
|
21
|
+
'''DEPRECATED on 2023.09.12, I{don't use}.'''
|
|
22
22
|
pass
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class _Deprecated_Str(Str):
|
|
26
|
-
'''DEPRECATED on 2023.09.12, don't use.'''
|
|
26
|
+
'''DEPRECATED on 2023.09.12, I{don't use}.'''
|
|
27
27
|
pass
|
|
28
28
|
|
|
29
29
|
|
pygeodesy/dms.py
CHANGED
|
@@ -62,11 +62,11 @@ U{Vector-based geodesy<https://www.Movable-Type.co.UK/scripts/latlong-vectors.ht
|
|
|
62
62
|
'''
|
|
63
63
|
|
|
64
64
|
from pygeodesy.basics import copysign0, isLatLon, isodd, issequence, isstr, \
|
|
65
|
-
neg as _neg # in .ups
|
|
65
|
+
neg as _neg, typename # in .ups
|
|
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
|
-
_parseX, rangerrors, _xError, _xkwds,
|
|
69
|
-
# from pygeodesy.internals import
|
|
68
|
+
_parseX, rangerrors, _xError, _xkwds, _envPYGEODESY
|
|
69
|
+
# from pygeodesy.internals import _envPYGEODESY, typename # from .errors
|
|
70
70
|
from pygeodesy.interns import NN, _COMMA_, _d_, _DASH_, _deg_, _degrees_, _DOT_, \
|
|
71
71
|
_0_, _e_, _E_, _EW_, _f_, _F_, _g_, _MINUS_, _N_, \
|
|
72
72
|
_NE_, _NS_, _NSEW_, _NW_, _PERCENTDOTSTAR_, _PLUS_, \
|
|
@@ -86,7 +86,7 @@ except ImportError: # Python 3+
|
|
|
86
86
|
from string import ascii_letters as _LETTERS
|
|
87
87
|
|
|
88
88
|
__all__ = _ALL_LAZY.dms
|
|
89
|
-
__version__ = '
|
|
89
|
+
__version__ = '25.04.14'
|
|
90
90
|
|
|
91
91
|
_beyond_ = 'beyond'
|
|
92
92
|
_deg_min_ = 'deg+min'
|
|
@@ -100,7 +100,7 @@ F_D_, F_DM_, F_DMS_, F_DEG_, F_MIN_, F_SEC_, F_D60_, F__E_, F__F_, F__G
|
|
|
100
100
|
F_D__, F_DM__, F_DMS__, F_DEG__, F_MIN__, F_SEC__, F_D60__, F__E__, F__F__, F__G__, F_RAD__ = (NN(
|
|
101
101
|
_PLUS_, _) for _ in _F_s)
|
|
102
102
|
del _F_s
|
|
103
|
-
_F_DMS =
|
|
103
|
+
_F_DMS = _envPYGEODESY('FMT_FORM') or F_DMS
|
|
104
104
|
|
|
105
105
|
_F_case = {F_D: F_D, F_DEG: F_D, _degrees_: F_D, # unsigned _F_s
|
|
106
106
|
F_DM: F_DM, F_MIN: F_DM, _deg_min_: F_DM,
|
|
@@ -348,7 +348,7 @@ def compassPoint(bearing, prec=3):
|
|
|
348
348
|
p = _MODS.units.Precision_(prec, low=1, high=4) \
|
|
349
349
|
if prec != 3 else int(prec)
|
|
350
350
|
m = 2 << p
|
|
351
|
-
w = 32 // m # if m
|
|
351
|
+
w = 32 // m # if _isin(m, 4, 8, 16, 32)
|
|
352
352
|
# not round(b), half-even rounding in Python 3+, but
|
|
353
353
|
# round-away-from-zero as int(b + copysign0(_0_5, b))
|
|
354
354
|
w *= int(b * m / _360_0 + _0_5) % m
|
|
@@ -483,7 +483,7 @@ def _latlonDMS_sep2(where, sep=None, **kwds):
|
|
|
483
483
|
i = _MODS.inters
|
|
484
484
|
k = Fmt.EQUAL(sep=repr(sep))
|
|
485
485
|
k = _SPACE_(i._keyword_, i._arg_, k, i._of_)
|
|
486
|
-
n = where
|
|
486
|
+
n = typename(where)
|
|
487
487
|
t = _latlonDMS_sep2.__doc__ % (sep, n)
|
|
488
488
|
_MODS.props._throwarning(k, n, t)
|
|
489
489
|
return sep, kwds
|
|
@@ -670,7 +670,7 @@ def _DDDMMSS6(t, S):
|
|
|
670
670
|
# check [D]DDMMSS form and compass point
|
|
671
671
|
X = _EW_ if isodd(n) else _NS_
|
|
672
672
|
if not (P in X or (S in X and (P.isdigit() or P == _DOT_))):
|
|
673
|
-
t = parseDDDMMSS
|
|
673
|
+
t = typename(parseDDDMMSS)[(5 if isodd(n) else 6):]
|
|
674
674
|
t = _SPACE_('form', t, 'applies', _DASH_.join(X))
|
|
675
675
|
raise ParseError(t)
|
|
676
676
|
else:
|
pygeodesy/ecef.py
CHANGED
|
@@ -57,24 +57,25 @@ for conversion between geodetic and I{local cartesian} coordinates in a I{local
|
|
|
57
57
|
plane} as opposed to I{geocentric} (ECEF) ones.
|
|
58
58
|
'''
|
|
59
59
|
|
|
60
|
-
from pygeodesy.basics import copysign0, isscalar, issubclassof, neg, map1, \
|
|
61
|
-
_xinstanceof, _xsubclassof # _args_kwds_names
|
|
60
|
+
from pygeodesy.basics import copysign0, _isin, isscalar, issubclassof, neg, map1, \
|
|
61
|
+
_xinstanceof, _xsubclassof, typename # _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, \
|
|
65
65
|
_100_0, _copysign_1_0, isnon0 # PYCHOK used!
|
|
66
|
-
from pygeodesy.datums import
|
|
66
|
+
from pygeodesy.datums import _ellipsoidal_datum, _WGS84, a_f2Tuple, _EWGS84
|
|
67
|
+
from pygeodesy.ecefLocals import _EcefLocal
|
|
67
68
|
# from pygeodesy.ellipsoids import a_f2Tuple, _EWGS84 # from .datums
|
|
68
69
|
from pygeodesy.errors import _IndexError, LenError, _ValueError, _TypesError, \
|
|
69
70
|
_xattr, _xdatum, _xkwds, _xkwds_get
|
|
70
|
-
from pygeodesy.fmath import cbrt, fdot,
|
|
71
|
+
from pygeodesy.fmath import cbrt, fdot, hypot, hypot1, hypot2_, sqrt0
|
|
71
72
|
from pygeodesy.fsums import Fsum, fsumf_, Fmt, unstr
|
|
73
|
+
# from pygeodesy.internals import typename # from .basics
|
|
72
74
|
from pygeodesy.interns import NN, _a_, _C_, _datum_, _ellipsoid_, _f_, _height_, \
|
|
73
75
|
_lat_, _lon_, _M_, _name_, _singular_, _SPACE_, \
|
|
74
76
|
_x_, _xyz_, _y_, _z_
|
|
75
77
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
76
|
-
from pygeodesy.named import _name__, _name1__, _NamedBase,
|
|
77
|
-
_NamedTuple, _Pass, _xnamed
|
|
78
|
+
from pygeodesy.named import _name__, _name1__, _NamedBase, _NamedTuple, _Pass, _xnamed
|
|
78
79
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, \
|
|
79
80
|
PhiLam2Tuple, Vector3Tuple, Vector4Tuple
|
|
80
81
|
from pygeodesy.props import deprecated_method, Property_RO, property_RO, \
|
|
@@ -89,7 +90,7 @@ from pygeodesy.utily import atan1, atan1d, atan2, atan2d, degrees90, degrees180,
|
|
|
89
90
|
from math import cos, degrees, fabs, radians, sqrt
|
|
90
91
|
|
|
91
92
|
__all__ = _ALL_LAZY.ecef
|
|
92
|
-
__version__ = '
|
|
93
|
+
__version__ = '25.04.28'
|
|
93
94
|
|
|
94
95
|
_Ecef_ = 'Ecef'
|
|
95
96
|
_prolate_ = 'prolate'
|
|
@@ -109,6 +110,7 @@ class _EcefBase(_NamedBase):
|
|
|
109
110
|
'''
|
|
110
111
|
_datum = _WGS84
|
|
111
112
|
_E = _EWGS84
|
|
113
|
+
_isYou = False
|
|
112
114
|
_lon00 = INT0 # arbitrary, "polar" lon for LocalCartesian, Ltp
|
|
113
115
|
|
|
114
116
|
def __init__(self, a_ellipsoid=_EWGS84, f=None, lon00=INT0, **name):
|
|
@@ -138,7 +140,7 @@ class _EcefBase(_NamedBase):
|
|
|
138
140
|
else:
|
|
139
141
|
raise ValueError() # _invalid_
|
|
140
142
|
|
|
141
|
-
if
|
|
143
|
+
if not _isin(E, _EWGS84, _WGS84):
|
|
142
144
|
d = _ellipsoidal_datum(E, **name)
|
|
143
145
|
E = d.ellipsoid
|
|
144
146
|
if E.a < EPS or E.f > EPS1:
|
|
@@ -271,12 +273,6 @@ class _EcefBase(_NamedBase):
|
|
|
271
273
|
return (Ecef9Tuple, # overwrite property_ROver
|
|
272
274
|
_MODS.vector3d.Vector3d) # _MODS.cartesianBase.CartesianBase
|
|
273
275
|
|
|
274
|
-
@Property_RO
|
|
275
|
-
def _isYou(self):
|
|
276
|
-
'''(INTERNAL) Is this an C{EcefYou}?.
|
|
277
|
-
'''
|
|
278
|
-
return isinstance(self, EcefYou)
|
|
279
|
-
|
|
280
276
|
@property
|
|
281
277
|
def lon00(self):
|
|
282
278
|
'''Get the I{"polar"} longitude (C{degrees}), see method C{reverse}.
|
|
@@ -789,6 +785,7 @@ class EcefYou(_EcefBase):
|
|
|
789
785
|
11589/115114_9021_geod2ellip_final.pdf>} Studia Geophysica et Geodaetica, 2008, 52,
|
|
790
786
|
pages 1-18 and U{PyMap3D <https://PyPI.org/project/pymap3d>}.
|
|
791
787
|
'''
|
|
788
|
+
_isYou = True
|
|
792
789
|
|
|
793
790
|
def __init__(self, a_ellipsoid=_EWGS84, f=None, **lon00_name): # PYCHOK signature
|
|
794
791
|
_EcefBase.__init__(self, a_ellipsoid, f=f, **lon00_name) # inherited documentation
|
|
@@ -824,13 +821,14 @@ class EcefYou(_EcefBase):
|
|
|
824
821
|
ellipsoid is I{prolate}.
|
|
825
822
|
'''
|
|
826
823
|
x, y, z, name = _xyzn4(xyz, y, z, self._Geocentrics, **lon00_name)
|
|
824
|
+
q = hypot(x, y) # R
|
|
827
825
|
|
|
828
826
|
E = self.ellipsoid
|
|
829
827
|
e, e2 = self._ee2
|
|
830
828
|
|
|
831
|
-
|
|
832
|
-
u
|
|
833
|
-
u
|
|
829
|
+
u = hypot2_(x, y, z) - e2
|
|
830
|
+
u += hypot(u, e * z * _2_0)
|
|
831
|
+
u *= _0_5
|
|
834
832
|
if u > EPS02:
|
|
835
833
|
u = sqrt(u)
|
|
836
834
|
p = hypot(u, e)
|
|
@@ -956,7 +954,7 @@ class EcefMatrix(_NamedTuple):
|
|
|
956
954
|
# <https://GeographicLib.SourceForge.io/C++/doc/LocalCartesian_8cpp_source.html>
|
|
957
955
|
# X = (fdot(self.column(r), *other.column(c)) for r in (0,1,2) for c in (0,1,2))
|
|
958
956
|
X = (fdot(self[r::3], *other[c::3]) for r in range(3) for c in range(3))
|
|
959
|
-
return _xnamed(EcefMatrix(*X), EcefMatrix.multiply
|
|
957
|
+
return _xnamed(EcefMatrix(*X), typename(EcefMatrix.multiply))
|
|
960
958
|
|
|
961
959
|
def rotate(self, xyz, *xyz0):
|
|
962
960
|
'''Forward rotation M{M0' ⋅ ([x, y, z] - [x0, y0, z0])'}.
|
|
@@ -1018,7 +1016,7 @@ class EcefMatrix(_NamedTuple):
|
|
|
1018
1016
|
return xyz_
|
|
1019
1017
|
|
|
1020
1018
|
|
|
1021
|
-
class Ecef9Tuple(_NamedTuple,
|
|
1019
|
+
class Ecef9Tuple(_NamedTuple, _EcefLocal):
|
|
1022
1020
|
'''9-Tuple C{(x, y, z, lat, lon, height, C, M, datum)} with I{geocentric} C{x},
|
|
1023
1021
|
C{y} and C{z} plus I{geodetic} C{lat}, C{lon} and C{height}, case C{C} (see
|
|
1024
1022
|
the C{Ecef*.reverse} methods) and optionally, rotation matrix C{M} (L{EcefMatrix})
|
|
@@ -1040,7 +1038,7 @@ class Ecef9Tuple(_NamedTuple, _NamedLocal):
|
|
|
1040
1038
|
return self.toDatum(datum2)
|
|
1041
1039
|
|
|
1042
1040
|
@property_RO
|
|
1043
|
-
def _ecef9(self):
|
|
1041
|
+
def _ecef9(self): # in ._EcefLocal._Ltp_ecef2local
|
|
1044
1042
|
return self
|
|
1045
1043
|
|
|
1046
1044
|
@Property_RO
|
|
@@ -1102,13 +1100,6 @@ class Ecef9Tuple(_NamedTuple, _NamedLocal):
|
|
|
1102
1100
|
'''
|
|
1103
1101
|
return Lon(Vermeille=degrees(self.lamVermeille))
|
|
1104
1102
|
|
|
1105
|
-
def _ltp_toLocal(self, ltp, Xyz_kwds, **Xyz): # overloads C{_NamedLocal}'s
|
|
1106
|
-
'''(INTERNAL) Invoke C{ltp._xLtp(ltp)._ecef2local}.
|
|
1107
|
-
'''
|
|
1108
|
-
Xyz_ = self._ltp_toLocal2(Xyz_kwds, **Xyz) # in ._NamedLocal
|
|
1109
|
-
ltp = self._ltp._xLtp(ltp, self._Ltp) # both in ._NamedLocal
|
|
1110
|
-
return ltp._ecef2local(self, *Xyz_)
|
|
1111
|
-
|
|
1112
1103
|
@Property_RO
|
|
1113
1104
|
def phi(self):
|
|
1114
1105
|
'''Get the latitude in C{radians} (C{float}).
|
|
@@ -1141,6 +1132,8 @@ class Ecef9Tuple(_NamedTuple, _NamedLocal):
|
|
|
1141
1132
|
'''
|
|
1142
1133
|
return PhiLam2Tuple(radians(self.lat), self.lamVermeille, name=self.name)
|
|
1143
1134
|
|
|
1135
|
+
phiVermeille = phi
|
|
1136
|
+
|
|
1144
1137
|
def toCartesian(self, Cartesian=None, **Cartesian_kwds):
|
|
1145
1138
|
'''Return the geocentric C{(x, y, z)} coordinates as an ellipsoidal or spherical
|
|
1146
1139
|
C{Cartesian}.
|
|
@@ -1157,7 +1150,7 @@ class Ecef9Tuple(_NamedTuple, _NamedLocal):
|
|
|
1157
1150
|
|
|
1158
1151
|
@raise TypeError: Invalid B{C{Cartesian}} or B{C{Cartesian_kwds}} item.
|
|
1159
1152
|
'''
|
|
1160
|
-
if Cartesian
|
|
1153
|
+
if _isin(Cartesian, None, Vector4Tuple):
|
|
1161
1154
|
r = self.xyzh
|
|
1162
1155
|
elif Cartesian is Vector3Tuple:
|
|
1163
1156
|
r = self.xyz
|
|
@@ -1177,7 +1170,7 @@ class Ecef9Tuple(_NamedTuple, _NamedLocal):
|
|
|
1177
1170
|
@raise TypeError: The B{C{datum2}} is not a L{Datum}.
|
|
1178
1171
|
'''
|
|
1179
1172
|
n = _name__(name, _or_nameof=self)
|
|
1180
|
-
if self.datum
|
|
1173
|
+
if _isin(self.datum, None, datum2): # PYCHOK _Names_
|
|
1181
1174
|
r = self.copy(name=n)
|
|
1182
1175
|
else:
|
|
1183
1176
|
c = self._CartesianBase(self, datum=self.datum, name=n) # PYCHOK _Names_
|
pygeodesy/ecefLocals.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''(INTERNAL) ECEF to local coodinate conversions, separated from
|
|
5
|
+
module C{ecef} to defer importing the latter into C{CartesianBase}
|
|
6
|
+
and C{LatLonBase}.
|
|
7
|
+
'''
|
|
8
|
+
|
|
9
|
+
from pygeodesy.basics import _isin, _xsubclassof
|
|
10
|
+
# from pygeodesy.ecef import EcefKarney # _MODS
|
|
11
|
+
from pygeodesy.errors import _xkwds_item2, _xkwds_pop2
|
|
12
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
13
|
+
# from pygeodesy import ltp as _ltp # _MODS.into
|
|
14
|
+
# from pygeodesy import ltpTuples as _ltpTuples # _MODS.into
|
|
15
|
+
from pygeodesy.named import _Named, notOverloaded
|
|
16
|
+
from pygeodesy.props import Property_RO, property_RO, property_ROver
|
|
17
|
+
|
|
18
|
+
__all__ = _ALL_LAZY.ecefLocals
|
|
19
|
+
__version__ = '25.04.28'
|
|
20
|
+
|
|
21
|
+
_ltp = _MODS.into(ltp=__name__)
|
|
22
|
+
_ltpTuples = _MODS.into(ltpTuples=__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _EcefLocal(_Named):
|
|
26
|
+
'''(INTERNAL) Base class for C{CartesianBase}, C{Ecef9Tuple} and
|
|
27
|
+
C{LatLonBase}, providing ECEF to local coordinate conversions.
|
|
28
|
+
'''
|
|
29
|
+
|
|
30
|
+
@property_ROver
|
|
31
|
+
def Ecef(self):
|
|
32
|
+
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
33
|
+
'''
|
|
34
|
+
return _MODS.ecef.EcefKarney
|
|
35
|
+
|
|
36
|
+
@property_RO
|
|
37
|
+
def _ecef9(self):
|
|
38
|
+
'''I{Must be overloaded}.'''
|
|
39
|
+
notOverloaded(self)
|
|
40
|
+
|
|
41
|
+
@property_RO
|
|
42
|
+
def _ecef9datum(self):
|
|
43
|
+
try:
|
|
44
|
+
d = self.datum # PYCHOK C{CartesianBase}, ...
|
|
45
|
+
except AttributeError:
|
|
46
|
+
d = None
|
|
47
|
+
return d or self._ecef9.datum
|
|
48
|
+
|
|
49
|
+
@Property_RO
|
|
50
|
+
def _ltp(self):
|
|
51
|
+
'''(INTERNAL) Cache this instance' LTP (L{Ltp}).
|
|
52
|
+
'''
|
|
53
|
+
return _ltp.Ltp(self._ecef9, ecef=self.Ecef(self._ecef9datum), name=self.name)
|
|
54
|
+
|
|
55
|
+
def _ltp_ecef2local(self, ltp, Xyz_kwds, _None=None, **Xyz): # in C{Ecef9Tuple}
|
|
56
|
+
'''(INTERNAL) Invoke C{_ltp._xLtp(ltp, self._ltp)._ecef2local}.
|
|
57
|
+
'''
|
|
58
|
+
C, _ = Xyz_ = _xkwds_pop2(Xyz_kwds, **Xyz)
|
|
59
|
+
if C is not _None: # validate C, see .toLocal
|
|
60
|
+
n, X = _xkwds_item2(Xyz)
|
|
61
|
+
if X is not C:
|
|
62
|
+
_xsubclassof(X, **{n: C})
|
|
63
|
+
ltp = _ltp._xLtp(ltp, self._ltp)
|
|
64
|
+
return ltp._ecef2local(self._ecef9, *Xyz_)
|
|
65
|
+
|
|
66
|
+
def toAer(self, ltp=None, **Aer_and_kwds):
|
|
67
|
+
'''Convert this instance to I{local} I{Azimuth, Elevation, slant Range} (AER) components.
|
|
68
|
+
|
|
69
|
+
@kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
|
|
70
|
+
instance' L{LTP<pygeodesy.ecefLocals._EcefLocal.toLtp>}.
|
|
71
|
+
@kwarg Aer_and_kwds: Optional AER class C{B{Aer}=}L{Aer<pygeodesy.ltpTuples.Aer>}
|
|
72
|
+
to use and optionally, additional B{C{Aer}} keyword arguments.
|
|
73
|
+
|
|
74
|
+
@return: An B{C{Aer}} instance.
|
|
75
|
+
|
|
76
|
+
@raise TypeError: Invalid B{C{ltp}}.
|
|
77
|
+
|
|
78
|
+
@see: Method L{toLocal<pygeodesy.ecefLocals._EcefLocal.toLocal>}.
|
|
79
|
+
'''
|
|
80
|
+
return self._ltp_ecef2local(ltp, Aer_and_kwds, Aer=_ltpTuples.Aer)
|
|
81
|
+
|
|
82
|
+
def toEnu(self, ltp=None, **Enu_and_kwds):
|
|
83
|
+
'''Convert this instance to I{local} I{East, North, Up} (ENU) components.
|
|
84
|
+
|
|
85
|
+
@kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
|
|
86
|
+
instance' L{LTP<pygeodesy.ecefLocals._EcefLocal.toLtp>}.
|
|
87
|
+
@kwarg Enu_and_kwds: Optional ENU class C{B{Enu}=}L{Enu<pygeodesy.ltpTuples.Enu>}
|
|
88
|
+
to use and optionally, additional B{C{Enu}} keyword arguments.
|
|
89
|
+
|
|
90
|
+
@return: An B{C{Enu}} instance.
|
|
91
|
+
|
|
92
|
+
@raise TypeError: Invalid B{C{ltp}}.
|
|
93
|
+
|
|
94
|
+
@see: Method L{toLocal<pygeodesy.ecefLocals._EcefLocal.toLocal>}.
|
|
95
|
+
'''
|
|
96
|
+
return self._ltp_ecef2local(ltp, Enu_and_kwds, Enu=_ltpTuples.Enu)
|
|
97
|
+
|
|
98
|
+
def toLocal(self, Xyz=None, ltp=None, **Xyz_kwds):
|
|
99
|
+
'''Convert this instance to I{local} components in a I{local tangent plane} (LTP)
|
|
100
|
+
|
|
101
|
+
@kwarg Xyz: Optional I{local} components class (L{XyzLocal}, L{Aer}, L{Enu},
|
|
102
|
+
L{Ned}) or C{None}.
|
|
103
|
+
@kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
|
|
104
|
+
cartesian's L{LTP<pygeodesy.ecefLocals._EcefLocal.toLtp>}.
|
|
105
|
+
@kwarg Xyz_kwds: Optionally, additional B{C{Xyz}} keyword arguments, ignored
|
|
106
|
+
if C{B{Xyz} is None}.
|
|
107
|
+
|
|
108
|
+
@return: An B{C{Xyz}} instance or a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
109
|
+
height, ltp, ecef, M)} if C{B{Xyz} is None} (with C{M=None}).
|
|
110
|
+
|
|
111
|
+
@raise TypeError: Invalid B{C{ltp}}.
|
|
112
|
+
'''
|
|
113
|
+
return self._ltp_ecef2local(ltp, Xyz_kwds, Xyz=Xyz, _None=Xyz)
|
|
114
|
+
|
|
115
|
+
def toLtp(self, Ecef=None, **name):
|
|
116
|
+
'''Return the I{local tangent plane} (LTP) for this instance.
|
|
117
|
+
|
|
118
|
+
@kwarg Ecef: Optional ECEF I{class} (L{EcefKarney}, ... L{EcefYou}), overriding
|
|
119
|
+
this instance' L{Ecef<pygeodesy.ecefLocals._EcefLocal.Ecef>}.
|
|
120
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
121
|
+
|
|
122
|
+
@return: An B{C{Ltp}} instance.
|
|
123
|
+
'''
|
|
124
|
+
if _isin(Ecef, None, self.Ecef) and not name:
|
|
125
|
+
ltp = self._ltp
|
|
126
|
+
else: # like self._ltp
|
|
127
|
+
ecef = (Ecef if Ecef else self.Ecef)(self._ecef9datum)
|
|
128
|
+
ltp = _ltp.Ltp(self._ecef9, ecef=ecef, name=self._name__(name))
|
|
129
|
+
return ltp
|
|
130
|
+
|
|
131
|
+
def toNed(self, ltp=None, **Ned_and_kwds):
|
|
132
|
+
'''Convert this instance to I{local} I{North, East, Down} (NED) components.
|
|
133
|
+
|
|
134
|
+
@kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
|
|
135
|
+
instance' L{LTP<pygeodesy.ecefLocals._EcefLocal.toLtp>}.
|
|
136
|
+
@kwarg Ned_and_kwds: Optional NED class C{B{Ned}=}L{Ned<pygeodesy.ltpTuples.Ned>}
|
|
137
|
+
to use and optionally, additional B{C{Ned}} keyword arguments.
|
|
138
|
+
|
|
139
|
+
@return: An B{C{Ned}} instance.
|
|
140
|
+
|
|
141
|
+
@raise TypeError: Invalid B{C{ltp}}.
|
|
142
|
+
|
|
143
|
+
@see: Method L{toLocal<pygeodesy.ecefLocals._EcefLocal.toLocal>}.
|
|
144
|
+
'''
|
|
145
|
+
return self._ltp_ecef2local(ltp, Ned_and_kwds, Ned=_ltpTuples.Ned)
|
|
146
|
+
|
|
147
|
+
def toXyz(self, ltp=None, **Xyz_and_kwds):
|
|
148
|
+
'''Convert this instance to I{local} I{X, Y, Z} (XYZ) components.
|
|
149
|
+
|
|
150
|
+
@kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
|
|
151
|
+
instance' L{LTP<pygeodesy.ecefLocals._EcefLocal.toLtp>}.
|
|
152
|
+
@kwarg Xyz_and_kwds: Optional XYZ class C{B{Xyz}=}L{Xyz<pygeodesy.ltpTuples.XyzLocal>}
|
|
153
|
+
to use and optionally, additional B{C{Xyz}} keyword arguments.
|
|
154
|
+
|
|
155
|
+
@return: An B{C{Xyz}} instance.
|
|
156
|
+
|
|
157
|
+
@raise TypeError: Invalid B{C{ltp}}.
|
|
158
|
+
|
|
159
|
+
@see: Method L{toLocal<pygeodesy.ecefLocals._EcefLocal.toLocal>}.
|
|
160
|
+
'''
|
|
161
|
+
return self._ltp_ecef2local(ltp, Xyz_and_kwds, Xyz=_ltpTuples.XyzLocal)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
__all__ += _ALL_DOCS(_EcefLocal)
|
|
165
|
+
|
|
166
|
+
# **) MIT License
|
|
167
|
+
#
|
|
168
|
+
# Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
169
|
+
#
|
|
170
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
171
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
172
|
+
# to deal in the Software without restriction, including without limitation
|
|
173
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
174
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
175
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
176
|
+
#
|
|
177
|
+
# The above copyright notice and this permission notice shall be included
|
|
178
|
+
# in all copies or substantial portions of the Software.
|
|
179
|
+
#
|
|
180
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
181
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
182
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
183
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
184
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
185
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
186
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
pygeodesy/elevations.py
CHANGED
|
@@ -21,11 +21,12 @@ U{USGS10mElev.py<https://Gist.GitHub.com/pyRobShrk>}.
|
|
|
21
21
|
C{"/Applications/Python\\ X.Y/Install\\ Certificates.command"}
|
|
22
22
|
'''
|
|
23
23
|
|
|
24
|
-
from pygeodesy.basics import clips, ub2str
|
|
24
|
+
from pygeodesy.basics import clips, ub2str, typename
|
|
25
25
|
from pygeodesy.errors import ParseError, _xkwds_get
|
|
26
|
-
from pygeodesy.
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
# from pygeodesy.internals import typename # from .basics
|
|
27
|
+
from pygeodesy.interns import NN, _AMPERSAND_, _COLONSPACE_, _DMAIN_, \
|
|
28
|
+
_elevation_, _height_, _LCURLY_, _n_a_, \
|
|
29
|
+
_no_, _RCURLY_, _SPACE_
|
|
29
30
|
from pygeodesy.lazily import _ALL_LAZY
|
|
30
31
|
from pygeodesy.named import _NamedTuple
|
|
31
32
|
from pygeodesy.streprs import fabs, Fmt, fstr, lrstrip
|
|
@@ -34,7 +35,7 @@ from pygeodesy.units import Lat, Lon, Meter, Scalar, Str
|
|
|
34
35
|
# from math import fabs # from .karney
|
|
35
36
|
|
|
36
37
|
__all__ = _ALL_LAZY.elevations
|
|
37
|
-
__version__ = '
|
|
38
|
+
__version__ = '25.04.14'
|
|
38
39
|
|
|
39
40
|
try:
|
|
40
41
|
from urllib2 import urlopen # quote, urlcleanup
|
|
@@ -91,7 +92,7 @@ except ImportError:
|
|
|
91
92
|
def _error(fun, lat, lon, e):
|
|
92
93
|
'''(INTERNAL) Format an error
|
|
93
94
|
'''
|
|
94
|
-
return _COLONSPACE_(Fmt.PAREN(fun
|
|
95
|
+
return _COLONSPACE_(Fmt.PAREN(typename(fun), fstr((lat, lon))), e)
|
|
95
96
|
|
|
96
97
|
|
|
97
98
|
def _qURL(url, timeout=2, **params):
|
|
@@ -243,14 +244,14 @@ def geoidHeight2(lat, lon, model=0, timeout=2.0):
|
|
|
243
244
|
return GeoidHeight2Tuple(None, e)
|
|
244
245
|
|
|
245
246
|
|
|
246
|
-
if __name__ ==
|
|
247
|
+
if __name__ == _DMAIN_:
|
|
247
248
|
|
|
248
249
|
from pygeodesy import printf
|
|
249
250
|
# <https://WikiPedia.org/wiki/Mount_Diablo>
|
|
250
251
|
for f in (elevation2, # (1173.79, '3DEP 1/3 arc-second')
|
|
251
252
|
geoidHeight2): # (-31.699, u'GEOID12B')
|
|
252
253
|
t = f(37.8816, -121.9142)
|
|
253
|
-
printf(_COLONSPACE_(f
|
|
254
|
+
printf(_COLONSPACE_(typename(f), t))
|
|
254
255
|
|
|
255
256
|
# **) MIT License
|
|
256
257
|
#
|
pygeodesy/ellipsoidalBase.py
CHANGED
|
@@ -12,30 +12,41 @@ and published under the same MIT Licence**, see for example U{latlon-ellipsoidal
|
|
|
12
12
|
# make sure int/int division yields float quotient, see .basics
|
|
13
13
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
14
14
|
|
|
15
|
-
# from pygeodesy.
|
|
15
|
+
# from pygeodesy.azimuthal import EquidistantExact, EquidistantKarney # _MODS
|
|
16
|
+
from pygeodesy.basics import _isin, _xinstanceof
|
|
16
17
|
from pygeodesy.constants import EPS, EPS0, EPS1, _0_0, _0_5
|
|
17
18
|
from pygeodesy.cartesianBase import CartesianBase # PYCHOK used!
|
|
19
|
+
# from pygeodesy.css import toCss # _MODS
|
|
18
20
|
from pygeodesy.datums import Datum, Datums, _earth_ellipsoid, _ellipsoidal_datum, \
|
|
19
|
-
Transform, _WGS84, _EWGS84
|
|
21
|
+
Transform, _WGS84, _EWGS84 # _spherical_datum
|
|
22
|
+
# from pygeodesy.dms import parse3llh # _MODS
|
|
23
|
+
# from pygeodesy.elevations import elevation2, geoidHeight2 # _MODS
|
|
24
|
+
# from pygeodesy.ellipsoidalBaseDI import _intersect3, _intersections2, _nearestOn2 # _MODS
|
|
20
25
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
21
26
|
from pygeodesy.errors import _IsnotError, RangeError, _TypeError, _xattr, _xellipsoidal, \
|
|
22
27
|
_xellipsoids, _xError, _xkwds, _xkwds_not
|
|
28
|
+
# from pygeodesy.etm import etm, toEtm8 # _MODS
|
|
23
29
|
# from pygeodesy.fmath import favg # _MODS
|
|
24
30
|
from pygeodesy.interns import NN, _COMMA_, _ellipsoidal_
|
|
25
31
|
from pygeodesy.latlonBase import LatLonBase, _trilaterate5, fabs, _Wrap
|
|
26
32
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
27
33
|
# from pygeodesy.lcc import toLcc # _MODS
|
|
28
34
|
# from pygeodesy.namedTuples import Vector3Tuple # _MODS
|
|
35
|
+
# from pygeodesy.osgr import toOsgr # _MODS
|
|
36
|
+
# from pygeodesy.points import isenclosedBy # _MODS
|
|
29
37
|
from pygeodesy.props import deprecated_method, deprecated_property_RO, \
|
|
30
38
|
Property_RO, property_doc_, property_RO, _update_all
|
|
31
|
-
# from pygeodesy.trf import
|
|
39
|
+
# from pygeodesy.trf import RefFrame, _toRefFrame # _MODS
|
|
32
40
|
from pygeodesy.units import Epoch, _isDegrees, Radius_, _1mm as _TOL_M
|
|
41
|
+
# from pygeodesy import ups, utm, utmups # MODS
|
|
42
|
+
# from pygeodesy.utmupsBase import _lowerleft # MODS
|
|
33
43
|
# from pygeodesy.utily import _Wrap # from .latlonBase
|
|
44
|
+
# from pygeodesy.vector3d import _intersects2 # _MODS
|
|
34
45
|
|
|
35
46
|
# from math import fabs # from .latlonBase
|
|
36
47
|
|
|
37
48
|
__all__ = _ALL_LAZY.ellipsoidalBase
|
|
38
|
-
__version__ = '
|
|
49
|
+
__version__ = '25.04.14'
|
|
39
50
|
|
|
40
51
|
|
|
41
52
|
class CartesianEllipsoidalBase(CartesianBase):
|
|
@@ -246,7 +257,7 @@ class LatLonEllipsoidalBase(LatLonBase):
|
|
|
246
257
|
@raise UnitError: Invalid B{C{lat}}, B{C{lon}} or B{C{height}}.
|
|
247
258
|
'''
|
|
248
259
|
LatLonBase.__init__(self, latlonh, lon=lon, height=height, wrap=wrap, **name)
|
|
249
|
-
if
|
|
260
|
+
if not _isin(datum, None, self._datum, _EWGS84):
|
|
250
261
|
self.datum = _ellipsoidal_datum(datum, name=self.name)
|
|
251
262
|
if reframe:
|
|
252
263
|
self.reframe = reframe
|
|
@@ -738,7 +749,7 @@ class LatLonEllipsoidalBase(LatLonBase):
|
|
|
738
749
|
n = Datums.NAD83.ellipsoid.rocGauss(self.lat)
|
|
739
750
|
if n > EPS0:
|
|
740
751
|
# use ratio, datum and NAD83 units may differ
|
|
741
|
-
E = self.ellipsoid() if datum
|
|
752
|
+
E = self.ellipsoid() if _isin(datum, None, self.datum) else \
|
|
742
753
|
_earth_ellipsoid(datum)
|
|
743
754
|
r = E.rocGauss(self.lat)
|
|
744
755
|
if r > EPS0 and fabs(r - n) > EPS: # EPS1
|
|
@@ -1109,9 +1120,9 @@ class LatLonEllipsoidalBase(LatLonBase):
|
|
|
1109
1120
|
def _lowerleft(utmups, center):
|
|
1110
1121
|
'''(INTERNAL) Optionally I{un}-center C{utmups}.
|
|
1111
1122
|
'''
|
|
1112
|
-
if center
|
|
1123
|
+
if _isin(center, False, 0, _0_0):
|
|
1113
1124
|
u = utmups
|
|
1114
|
-
elif center
|
|
1125
|
+
elif _isin(center, True):
|
|
1115
1126
|
u = utmups._lowerleft
|
|
1116
1127
|
else:
|
|
1117
1128
|
u = _MODS.utmupsBase._lowerleft(utmups, center)
|