pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.9__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.24.dist-info → PyGeodesy-24.6.9.dist-info}/METADATA +6 -5
- PyGeodesy-24.6.9.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +4 -4
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +4 -4
- pygeodesy/basics.py +39 -5
- pygeodesy/booleans.py +54 -67
- pygeodesy/cartesianBase.py +138 -147
- pygeodesy/constants.py +3 -3
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/ecef.py +67 -72
- pygeodesy/ellipsoidalBase.py +18 -56
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoidalNvector.py +7 -7
- pygeodesy/ellipsoids.py +6 -5
- pygeodesy/errors.py +20 -10
- pygeodesy/etm.py +16 -21
- pygeodesy/fmath.py +9 -20
- pygeodesy/formy.py +60 -74
- pygeodesy/frechet.py +13 -14
- pygeodesy/fsums.py +60 -26
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +3 -5
- pygeodesy/geodsolve.py +24 -26
- pygeodesy/geohash.py +27 -40
- pygeodesy/geoids.py +1 -1
- pygeodesy/hausdorff.py +17 -18
- pygeodesy/heights.py +17 -30
- pygeodesy/internals.py +15 -14
- pygeodesy/interns.py +3 -9
- pygeodesy/iters.py +2 -2
- pygeodesy/karney.py +8 -7
- pygeodesy/latlonBase.py +189 -176
- pygeodesy/lazily.py +92 -56
- pygeodesy/lcc.py +2 -2
- pygeodesy/ltp.py +93 -55
- pygeodesy/ltpTuples.py +304 -240
- pygeodesy/mgrs.py +51 -24
- pygeodesy/named.py +159 -136
- pygeodesy/namedTuples.py +43 -14
- pygeodesy/nvectorBase.py +20 -23
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +11 -11
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +20 -70
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +35 -32
- pygeodesy/sphericalBase.py +33 -31
- pygeodesy/sphericalTrigonometry.py +17 -17
- pygeodesy/streprs.py +6 -4
- pygeodesy/trf.py +11 -9
- pygeodesy/triaxials.py +71 -50
- pygeodesy/units.py +40 -65
- pygeodesy/unitsBase.py +2 -2
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +7 -6
- pygeodesy/utm.py +152 -156
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +102 -106
- pygeodesy/vector3d.py +34 -36
- pygeodesy/vector3dBase.py +12 -9
- pygeodesy/webmercator.py +43 -51
- PyGeodesy-24.5.24.dist-info/RECORD +0 -116
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/top_level.txt +0 -0
pygeodesy/lazily.py
CHANGED
|
@@ -29,39 +29,33 @@ and line number.
|
|
|
29
29
|
|
|
30
30
|
from pygeodesy import internals as _internals, interns as _interns, \
|
|
31
31
|
_isfrozen # DON'T _lazy_import2
|
|
32
|
-
# from pygeodesy.errors import _error_init # _ALL_MODS
|
|
32
|
+
# from pygeodesy.errors import _error_init, _xkwds_item2 # _ALL_MODS
|
|
33
33
|
from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_ismain, \
|
|
34
34
|
_headof, _osversion2, printf, _Pythonarchine, \
|
|
35
|
-
_tailof
|
|
36
|
-
from pygeodesy.interns import NN,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
_pygeodesy_abspath_, _SouthPole_, \
|
|
42
|
-
_SPACE_, _sub_packages, _sys, _UNDER_, _version_, \
|
|
35
|
+
_tailof # _Property_RO
|
|
36
|
+
from pygeodesy.interns import NN, _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, \
|
|
37
|
+
_doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
|
|
38
|
+
_HASH_, _immutable_, _line_, _module_, _no_, _not_, \
|
|
39
|
+
_or_, _pygeodesy_abspath_, _pygeodesy_, _SPACE_, \
|
|
40
|
+
_SUB_PACKAGES, _UNDER_, _version_, _sys, \
|
|
43
41
|
_intern # function
|
|
44
42
|
# from pygeodesy.streprs import unstr # _ALL_MODS
|
|
45
43
|
|
|
46
|
-
from os import getenv as _getenv
|
|
47
44
|
try:
|
|
48
45
|
from importlib import import_module
|
|
49
46
|
except ImportError as x: # Python 2.6-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
t = _ALL_MODS.streprs.unstr(import_module, name, *package)
|
|
54
|
-
raise LazyImportError(t, txt=_str_x)
|
|
47
|
+
raise ImportError(_COLONSPACE_(_Pythonarchine(sep=_SPACE_), x))
|
|
48
|
+
from os import getenv as _getenv
|
|
49
|
+
# import sys as _sys # from .interns
|
|
55
50
|
|
|
56
51
|
__as__ = ' as '
|
|
57
52
|
_dunder_all_ = '__all__' # in .__main__
|
|
58
|
-
|
|
53
|
+
_enabled_ = 'enabled'
|
|
59
54
|
_FOR_DOCS = _getenv('PYGEODESY_FOR_DOCS', NN) # for epydoc ...
|
|
60
|
-
_from_DOT__ = _SPACE_(NN, _from_, _DOT_)
|
|
61
55
|
_i0 = () # PYCHOK empty tuple
|
|
62
56
|
_init__all__ = _FOR_DOCS or _getenv('PYGEODESY_INIT__ALL__', _dunder_all_) == _dunder_all_ # PYCHOK exported
|
|
63
57
|
_lazily_ = 'lazily'
|
|
64
|
-
|
|
58
|
+
_lazily_imported_ = _SPACE_(_HASH_, _lazily_, 'imported')
|
|
65
59
|
_PYGEODESY_GEOCONVERT_ = 'PYGEODESY_GEOCONVERT' # PYCHOK .mgrs, test.bases
|
|
66
60
|
_PYGEODESY_GEODSOLVE_ = 'PYGEODESY_GEODSOLVE' # PYCHOK .geodsolve, test.bases
|
|
67
61
|
_PYGEODESY_LAZY_IMPORT_ = 'PYGEODESY_LAZY_IMPORT'
|
|
@@ -73,7 +67,7 @@ _unlazy = _unLazy0 = _isfrozen or _sys_version_info2 < (3, 7) # PYCHOK mod
|
|
|
73
67
|
_WARNINGS_X_DEV = _getenv('PYGEODESY_WARNINGS', NN) and (
|
|
74
68
|
_PYTHON_X_DEV or bool(_sys.warnoptions)) # PYCHOK .props
|
|
75
69
|
# @module_property[_RO?] <https://GitHub.com/jtushman/proxy_tools/>
|
|
76
|
-
isLazy =
|
|
70
|
+
isLazy = None # see @var isLazy in .__init__
|
|
77
71
|
|
|
78
72
|
|
|
79
73
|
class LazyAttributeError(AttributeError):
|
|
@@ -168,7 +162,7 @@ class _NamedEnum_RO(dict):
|
|
|
168
162
|
for a in t:
|
|
169
163
|
a, _, as_ = a.partition(__as__)
|
|
170
164
|
if as_: # import attr as attr_
|
|
171
|
-
_a(as_, _DOT_(m, a, NN), *
|
|
165
|
+
_a(as_, _DOT_(m, a, NN), *_SUB_PACKAGES)
|
|
172
166
|
else:
|
|
173
167
|
_a(a, m)
|
|
174
168
|
return _D
|
|
@@ -185,7 +179,7 @@ def _ALL_ATTRS(*attrs):
|
|
|
185
179
|
'''
|
|
186
180
|
t = ()
|
|
187
181
|
for attr in attrs:
|
|
188
|
-
t += tuple(map(
|
|
182
|
+
t += tuple(map(_getattrof, attr))
|
|
189
183
|
return t
|
|
190
184
|
|
|
191
185
|
|
|
@@ -269,7 +263,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
269
263
|
'antipode', 'antipode_', 'bearing', 'bearing_',
|
|
270
264
|
'compassAngle', 'cosineForsytheAndoyerLambert', 'cosineForsytheAndoyerLambert_',
|
|
271
265
|
'cosineAndoyerLambert', 'cosineAndoyerLambert_', 'cosineLaw', 'cosineLaw_',
|
|
272
|
-
'equirectangular', '
|
|
266
|
+
'equirectangular', 'equirectangular4', 'euclidean', 'euclidean_',
|
|
273
267
|
'excessAbc_', 'excessCagnoli_', 'excessGirard_', 'excessLHuilier_',
|
|
274
268
|
'excessKarney', 'excessKarney_', 'excessQuad', 'excessQuad_',
|
|
275
269
|
'flatLocal', 'flatLocal_', 'flatPolar', 'flatPolar_',
|
|
@@ -290,7 +284,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
290
284
|
'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
|
|
291
285
|
gars=_i('Garef', 'GARSError'),
|
|
292
286
|
geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
|
|
293
|
-
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
287
|
+
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
294
288
|
'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
|
|
295
289
|
geodsolve=_i('GeodesicSolve', 'GeodesicLineSolve', 'GeodSolve12Tuple'),
|
|
296
290
|
geohash=_i('Geohash', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple'),
|
|
@@ -340,11 +334,11 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
340
334
|
'Reverse4Tuple', 'Triangle7Tuple', 'Triangle8Tuple', 'Trilaterate5Tuple',
|
|
341
335
|
'UtmUps2Tuple', 'UtmUps5Tuple', 'UtmUps8Tuple', 'UtmUpsLatLon5Tuple',
|
|
342
336
|
'Vector2Tuple', 'Vector3Tuple', 'Vector4Tuple'),
|
|
343
|
-
nvectorBase=_i(
|
|
337
|
+
nvectorBase=_i('NorthPole', 'SouthPole'),
|
|
344
338
|
osgr=_i('Osgr', 'OSGRError', 'parseOSGR', 'toOsgr'),
|
|
345
339
|
points=_i('LatLon_', 'LatLon2psxy', 'Numpy2LatLon', 'Shape2Tuple', 'Tuple2LatLon',
|
|
346
|
-
|
|
347
|
-
|
|
340
|
+
'areaOf', 'boundsOf', 'centroidOf', 'fractional',
|
|
341
|
+
'isclockwise', 'isconvex', 'isconvex_', 'isenclosedBy', 'ispolar',
|
|
348
342
|
'luneOf', 'nearestOn5', 'perimeterOf', 'quadOf'),
|
|
349
343
|
props=_i('Property', 'Property_RO', 'property_RO', 'property_doc_',
|
|
350
344
|
'deprecated_class', 'deprecated_function', 'deprecated_method',
|
|
@@ -421,7 +415,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
421
415
|
'R_M', 'R_MA', 'R_MB', 'R_KM', 'R_NM', 'R_SM', 'R_FM', 'R_VM'),
|
|
422
416
|
deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ...
|
|
423
417
|
'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ... ellipsoidal, spherical flavors
|
|
424
|
-
'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular3',
|
|
418
|
+
'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular_', 'equirectangular3',
|
|
425
419
|
'excessAbc', 'excessGirard', 'excessLHuilier',
|
|
426
420
|
'false2f', 'falsed2f', 'float0', 'fStr', 'fStrzs', 'hypot3',
|
|
427
421
|
'inStr', 'isenclosedby', 'istuplist',
|
|
@@ -432,7 +426,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
432
426
|
deprecated_nvector=_i('LatLonNvectorBase', 'Nvector', 'sumOf', 'NorthPole', 'SouthPole'),)
|
|
433
427
|
|
|
434
428
|
|
|
435
|
-
class _ALL_MODS(_internals.
|
|
429
|
+
class _ALL_MODS(_internals._MODS_Base):
|
|
436
430
|
'''(INTERNAL) Memoized import of any L{pygeodesy} module.
|
|
437
431
|
'''
|
|
438
432
|
def __getattr__(self, name):
|
|
@@ -474,7 +468,7 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
|
|
|
474
468
|
return v
|
|
475
469
|
|
|
476
470
|
def getmodule(self, name, parent=_pygeodesy_):
|
|
477
|
-
'''Get a C{pygeodesy} module.
|
|
471
|
+
'''Get a C{pygeodesy} module or the C{__main__}.
|
|
478
472
|
|
|
479
473
|
@arg name: Un/qualified module name (C{str}).
|
|
480
474
|
|
|
@@ -482,12 +476,36 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
|
|
|
482
476
|
|
|
483
477
|
@raise ImportError: Importing module B{C{name}} failed.
|
|
484
478
|
'''
|
|
485
|
-
if _headof(name) != parent:
|
|
479
|
+
if _headof(name) != parent and not _dunder_ismain(name):
|
|
486
480
|
name = _DOT_(parent, name)
|
|
487
481
|
try:
|
|
488
482
|
return _sys.modules[name]
|
|
489
483
|
except KeyError:
|
|
490
|
-
return
|
|
484
|
+
return _getmodule(name, parent)
|
|
485
|
+
|
|
486
|
+
def into(self, **mod_dunder_name_):
|
|
487
|
+
'''Lazily import module C{mod} into module C{_dunder_name_}
|
|
488
|
+
and set C{_dunder_name_._mod} to module C{mod}, I{once}.
|
|
489
|
+
'''
|
|
490
|
+
class _Into(object):
|
|
491
|
+
|
|
492
|
+
def __getattr__(unused, name):
|
|
493
|
+
mod, dun = self.errors._xkwds_item2(mod_dunder_name_)
|
|
494
|
+
_mod = _UNDER_(NN, mod)
|
|
495
|
+
d = self.getmodule(dun) # '__main__' OK
|
|
496
|
+
i = _getattribute(d, _mod, dun)
|
|
497
|
+
assert isinstance(i, _Into)
|
|
498
|
+
m = self.getmodule(mod)
|
|
499
|
+
setattr(d, _mod, m) # overwrite C{d._mod}
|
|
500
|
+
return getattr(m, name)
|
|
501
|
+
|
|
502
|
+
return _Into()
|
|
503
|
+
|
|
504
|
+
# @_Property_RO
|
|
505
|
+
# def _isBoolean(self):
|
|
506
|
+
# '''(INTERNAL) Get function C(.booleans.isBoolean}, I{once}.
|
|
507
|
+
# '''
|
|
508
|
+
# return self.booleans.isBoolean
|
|
491
509
|
|
|
492
510
|
def items(self): # no module named 'items'
|
|
493
511
|
'''Yield the modules imported so far.
|
|
@@ -500,7 +518,7 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
|
|
|
500
518
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
501
519
|
|
|
502
520
|
__all__ = _ALL_LAZY.lazily
|
|
503
|
-
__version__ = '24.05
|
|
521
|
+
__version__ = '24.06.05'
|
|
504
522
|
|
|
505
523
|
|
|
506
524
|
def _ALL_OTHER(*objs):
|
|
@@ -565,11 +583,34 @@ def _all_missing2(_all_):
|
|
|
565
583
|
(_DOT_(_pygeodesy_, _dunder_all_), _diff(_alzy.keys(), _all_)))
|
|
566
584
|
|
|
567
585
|
|
|
568
|
-
def
|
|
586
|
+
def _getattribute(m, name, mod=_pygeodesy_):
|
|
587
|
+
'''(INTERNAL) Get attr C{m.name}.
|
|
588
|
+
'''
|
|
589
|
+
try:
|
|
590
|
+
return getattr(m, name)
|
|
591
|
+
except AttributeError:
|
|
592
|
+
name = _DOT_(mod, name)
|
|
593
|
+
# <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
|
|
594
|
+
raise LazyAttributeError(_no_(_attribute_), txt=name)
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
def _getattrof(attr_as): # .testDeprecated
|
|
598
|
+
'''(INTERNAL) Get the C{"as name"} or C{"name"} of a lazy entry.
|
|
599
|
+
'''
|
|
569
600
|
a_, _, as_ = attr_as.partition(__as__)
|
|
570
601
|
return as_ or a_.rstrip(_DOT_)
|
|
571
602
|
|
|
572
603
|
|
|
604
|
+
def _getmodule(name, *parent):
|
|
605
|
+
'''(INTERNAL) Wrapper for C{import_module}.
|
|
606
|
+
'''
|
|
607
|
+
try:
|
|
608
|
+
return import_module(name, parent)
|
|
609
|
+
except ImportError:
|
|
610
|
+
# <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
|
|
611
|
+
raise LazyImportError(_no_(_module_), txt=name)
|
|
612
|
+
|
|
613
|
+
|
|
573
614
|
# def _lazy_attributes(_dunder_name_):
|
|
574
615
|
# '''(INTERNAL) Return a function to C{B{__name__}.__getattr__(attr)}
|
|
575
616
|
# on lazily imported modules and sub-modules.
|
|
@@ -615,17 +656,19 @@ def _lazy_import2(pack): # MCCABE 14
|
|
|
615
656
|
U{PEP 562<https://www.Python.org/dev/peps/pep-0562>} and the
|
|
616
657
|
U{new way<https://Snarky.Ca/lazy-importing-in-python-3-7/>}.
|
|
617
658
|
'''
|
|
659
|
+
_DOT_ = _interns._DOT_
|
|
660
|
+
_SPACE_ = _interns._SPACE_
|
|
661
|
+
|
|
618
662
|
if pack != _pygeodesy_ or _unlazy: # Python 3.7+
|
|
619
663
|
t = _no_(_DOT_(pack, _dunder_nameof(_lazy_import2))) # PYCHOK no cover
|
|
620
664
|
raise LazyImportError(t, txt=_Pythonarchine(sep=_SPACE_))
|
|
621
665
|
|
|
622
|
-
package, parent
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
deprecates = _all_deprecates()
|
|
666
|
+
package, parent = _lazy_init2(pack) # _pygeodesy_
|
|
667
|
+
sub_packages = set((parent, NN) + tuple(
|
|
668
|
+
_DOT_(parent, s) for s in _SUB_PACKAGES))
|
|
669
|
+
imports = _all_imports()
|
|
670
|
+
deprecates = _all_deprecates()
|
|
671
|
+
_dunder_package_ = '__package__'
|
|
629
672
|
|
|
630
673
|
def __getattr__(name): # __getattr__ only for Python 3.7+
|
|
631
674
|
# only called once for each undefined pygeodesy attribute
|
|
@@ -638,21 +681,12 @@ def _lazy_import2(pack): # MCCABE 14
|
|
|
638
681
|
mod, _, attr = mod[:-1].rpartition(_DOT_)
|
|
639
682
|
else: # from mod import name
|
|
640
683
|
attr = name
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
except ImportError:
|
|
645
|
-
# <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
|
|
646
|
-
raise LazyImportError(_no_(_module_), txt=t)
|
|
647
|
-
t = getattr(v, _dunder_package_, None)
|
|
648
|
-
if t not in subpacks: # invalid module package
|
|
684
|
+
v = _getmodule(_DOT_(pack, mod), parent)
|
|
685
|
+
t = getattr(v, _dunder_package_, None)
|
|
686
|
+
if t not in sub_packages: # invalid module package
|
|
649
687
|
raise LazyImportError(_DOT_(mod, _dunder_package_), t)
|
|
650
|
-
if attr: # get
|
|
651
|
-
v =
|
|
652
|
-
if v is MISSING: # PYCHOK no cover
|
|
653
|
-
t = _DOT_(mod, attr)
|
|
654
|
-
# <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
|
|
655
|
-
raise LazyAttributeError(_no_(_attribute_), txt=t)
|
|
688
|
+
if attr: # get mod.attr
|
|
689
|
+
v = _getattribute(v, attr, mod)
|
|
656
690
|
|
|
657
691
|
elif name in (_dunder_all_,): # XXX _dunder_dir_, _dunder_members_?
|
|
658
692
|
v = _ALL_INIT + tuple(imports.keys())
|
|
@@ -663,9 +697,9 @@ def _lazy_import2(pack): # MCCABE 14
|
|
|
663
697
|
|
|
664
698
|
setattr(package, name, v) # package.__dict__[name] = val
|
|
665
699
|
if isLazy > 1:
|
|
666
|
-
t =
|
|
700
|
+
t = _SPACE_(_lazily_imported_, _DOT_(parent, name))
|
|
667
701
|
if mod and _tailof(mod) != name:
|
|
668
|
-
t =
|
|
702
|
+
t = _SPACE_(t, _from_, _DOT_(NN, mod))
|
|
669
703
|
if isLazy > 2:
|
|
670
704
|
try: # see C{_caller3}
|
|
671
705
|
_, f, s = _caller3(2)
|
|
@@ -827,6 +861,8 @@ def _lazy_module(name): # overwritten by _lazy_import2
|
|
|
827
861
|
|
|
828
862
|
# del _i, _i0
|
|
829
863
|
|
|
864
|
+
# _ = _ALL_MODS.errors # force import pygeodesy.errors
|
|
865
|
+
|
|
830
866
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
831
867
|
|
|
832
868
|
from timeit import timeit
|
pygeodesy/lcc.py
CHANGED
|
@@ -48,7 +48,7 @@ from pygeodesy.utily import atan1, degrees90, degrees180, sincos2, tanPI_2_2
|
|
|
48
48
|
from math import atan, fabs, log, radians, sin, sqrt
|
|
49
49
|
|
|
50
50
|
__all__ = _ALL_LAZY.lcc
|
|
51
|
-
__version__ = '24.
|
|
51
|
+
__version__ = '24.06.09'
|
|
52
52
|
|
|
53
53
|
_E0_ = 'E0'
|
|
54
54
|
_N0_ = 'N0'
|
|
@@ -454,7 +454,7 @@ class Lcc(_NamedBase):
|
|
|
454
454
|
#
|
|
455
455
|
# kwds = _xkwds(e_n_h_conic, e=self.easting, n=self.northing,
|
|
456
456
|
# h=self.height, conic=self.conic,
|
|
457
|
-
# name=
|
|
457
|
+
# name=self._name__(name))
|
|
458
458
|
# args, kwds = _args_kwds(**kwds)
|
|
459
459
|
# return self.__class__(*args, **kwds) # .classof
|
|
460
460
|
|
pygeodesy/ltp.py
CHANGED
|
@@ -13,23 +13,25 @@ and L{ChLVe} and L{Ltp}, L{ChLV}, L{LocalError}, L{Attitude} and L{Frustum}.
|
|
|
13
13
|
# make sure int/int division yields float quotient, see .basics
|
|
14
14
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
15
15
|
|
|
16
|
-
from pygeodesy.basics import _args_kwds_names,
|
|
16
|
+
from pygeodesy.basics import _args_kwds_names, map1, map2, _xinstanceof, \
|
|
17
|
+
_xsubclassof # .datums
|
|
17
18
|
from pygeodesy.constants import EPS, INT0, _umod_360, _0_0, _0_01, _0_5, _1_0, \
|
|
18
19
|
_2_0, _60_0, _90_0, _100_0, _180_0, _3600_0, \
|
|
19
20
|
_N_1_0 # PYCHOK used!
|
|
20
|
-
from pygeodesy.datums import _WGS84
|
|
21
|
-
from pygeodesy.ecef import _EcefBase, EcefKarney, _llhn4,
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
# from pygeodesy.datums import _WGS84 # from .ecef
|
|
22
|
+
from pygeodesy.ecef import _EcefBase, EcefKarney, Ecef9Tuple, _llhn4, \
|
|
23
|
+
_xyzn4, _WGS84
|
|
24
|
+
from pygeodesy.errors import _NotImplementedError, _ValueError, _xattr, \
|
|
25
|
+
_xkwds, _xkwds_get, _xkwds_pop2
|
|
24
26
|
from pygeodesy.fmath import fabs, fdot, Fhorner
|
|
25
27
|
from pygeodesy.fsums import _floor, _Fsumf_, fsumf_, fsum1f_
|
|
26
28
|
from pygeodesy.interns import _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, _M_, \
|
|
27
|
-
_invalid_, _lat0_, _lon0_,
|
|
29
|
+
_invalid_, _lat0_, _lon0_, _name_, _too_
|
|
28
30
|
# from pygeodesy.lazily import _ALL_LAZY # from vector3d
|
|
29
31
|
from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
|
|
30
32
|
ChLVYX2Tuple, Footprint5Tuple, Local9Tuple, \
|
|
31
33
|
ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
|
|
32
|
-
from pygeodesy.named import _name__, _NamedBase, notOverloaded
|
|
34
|
+
from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
|
|
33
35
|
from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
|
|
34
36
|
from pygeodesy.props import Property, Property_RO, property_doc_, property_RO, \
|
|
35
37
|
_update_all
|
|
@@ -42,25 +44,15 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
|
|
|
42
44
|
# from math import fabs, floor as _floor # from .fmath, .fsums
|
|
43
45
|
|
|
44
46
|
__all__ = _ALL_LAZY.ltp
|
|
45
|
-
__version__ = '24.
|
|
47
|
+
__version__ = '24.06.07'
|
|
46
48
|
|
|
47
49
|
_height0_ = _height_ + _0_
|
|
48
50
|
_narrow_ = 'narrow'
|
|
49
51
|
_wide_ = 'wide'
|
|
50
|
-
_Xyz_ = 'Xyz'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _fov_2(**fov):
|
|
54
|
-
# Half a field-of-view angle in C{degrees}.
|
|
55
|
-
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
56
|
-
if EPS < f < _90_0:
|
|
57
|
-
return f
|
|
58
|
-
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
59
|
-
raise LocalError(txt=t, **fov)
|
|
60
52
|
|
|
61
53
|
|
|
62
54
|
class Attitude(_NamedBase):
|
|
63
|
-
'''The
|
|
55
|
+
'''The pose of a plane or camera in space.
|
|
64
56
|
'''
|
|
65
57
|
_alt = Meter( alt =_0_0)
|
|
66
58
|
_roll = Degrees(roll=_0_0)
|
|
@@ -70,9 +62,9 @@ class Attitude(_NamedBase):
|
|
|
70
62
|
def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, **name):
|
|
71
63
|
'''New L{Attitude}.
|
|
72
64
|
|
|
73
|
-
@kwarg alt_attitude:
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
@kwarg alt_attitude: Altitude (C{meter}) above earth or previous attitude
|
|
66
|
+
(L{Attitude} or L{Attitude4Tuple}) with the C{B{alt}itude},
|
|
67
|
+
B{C{tilt}}, B{C{yaw}} and B{C{roll}}.
|
|
76
68
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees180}), negative down
|
|
77
69
|
(clockwise rotation along and around the x- or East axis).
|
|
78
70
|
@kwarg yaw: Bearing, heading (compass C{degrees360}), clockwise from North
|
|
@@ -149,23 +141,26 @@ class Attitude(_NamedBase):
|
|
|
149
141
|
|
|
150
142
|
bank = roll
|
|
151
143
|
|
|
152
|
-
def rotate(self, x_xyz, y=None, z=None, Vector=None, **
|
|
144
|
+
def rotate(self, x_xyz, y=None, z=None, Vector=None, **name_Vector_kwds):
|
|
153
145
|
'''Transform a (local) cartesian by this attitude's matrix.
|
|
154
146
|
|
|
155
|
-
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector
|
|
156
|
-
|
|
147
|
+
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Cartesian},
|
|
148
|
+
L{Vector3d} or L{Vector3Tuple}).
|
|
157
149
|
@kwarg y: Y component of vector (C{scalar}), same units as B{C{x}}.
|
|
158
150
|
@kwarg z: Z component of vector (C{scalar}), same units as B{C{x}}.
|
|
159
|
-
@kwarg Vector: Class to return transformed point (C{Cartesian},
|
|
160
|
-
|
|
161
|
-
@kwarg
|
|
162
|
-
|
|
151
|
+
@kwarg Vector: Class to return transformed point (C{Cartesian}, L{Vector3d}
|
|
152
|
+
or C{Vector3Tuple}) or C{None}.
|
|
153
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
154
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
155
|
+
C{B{Vector} is None}.
|
|
163
156
|
|
|
164
|
-
@return: A B{C{Vector}} instance or
|
|
165
|
-
C{
|
|
157
|
+
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
158
|
+
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
166
159
|
|
|
167
160
|
@raise AttitudeError: Invalid B{C{x_xyz}}, B{C{y}} or B{C{z}}.
|
|
168
161
|
|
|
162
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
163
|
+
|
|
169
164
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}.
|
|
170
165
|
'''
|
|
171
166
|
try:
|
|
@@ -177,8 +172,9 @@ class Attitude(_NamedBase):
|
|
|
177
172
|
raise AttitudeError(x_xyz=x_xyz, y=y, z=z, cause=x)
|
|
178
173
|
|
|
179
174
|
x, y, z = (fdot(r, *xyz) for r in self.matrix)
|
|
180
|
-
|
|
181
|
-
|
|
175
|
+
n, kwds = _name2__(name_Vector_kwds, _or_nameof=self)
|
|
176
|
+
return Vector3Tuple(x, y, z, name=n) if Vector is None else \
|
|
177
|
+
Vector(x, y, z, name=n, **kwds)
|
|
182
178
|
|
|
183
179
|
@property_doc_(' tilt/pitch/elevation from horizontal in C{degrees180}, negative down.')
|
|
184
180
|
def tilt(self):
|
|
@@ -469,29 +465,34 @@ class LocalCartesian(_NamedBase):
|
|
|
469
465
|
'''
|
|
470
466
|
return self._ecef
|
|
471
467
|
|
|
472
|
-
def _ecef2local(self, ecef, Xyz,
|
|
468
|
+
def _ecef2local(self, ecef, Xyz, name_Xyz_kwds):
|
|
473
469
|
'''(INTERNAL) Convert geocentric/geodetic to local, like I{forward}.
|
|
474
470
|
|
|
475
471
|
@arg ecef: Geocentric (and geodetic) (L{Ecef9Tuple}).
|
|
476
472
|
@arg Xyz: An L{XyzLocal}, L{Enu} or L{Ned} I{class} or C{None}.
|
|
477
|
-
@arg
|
|
473
|
+
@arg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
474
|
+
additional B{C{Xyz}} keyword arguments, ignored if
|
|
475
|
+
C{B{Xyz} is None}.
|
|
478
476
|
|
|
479
|
-
@return: An C{B{Xyz}(x, y, z, ltp, **B{
|
|
480
|
-
C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
477
|
+
@return: An C{B{Xyz}(x, y, z, ltp, **B{name_Xyz_kwds}} instance or
|
|
478
|
+
if C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
481
479
|
height, ltp, ecef, M)} with this C{ltp}, B{C{ecef}}
|
|
482
480
|
(L{Ecef9Tuple}) converted to this C{datum} and C{M=None},
|
|
483
481
|
always.
|
|
482
|
+
|
|
483
|
+
@raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
|
|
484
484
|
'''
|
|
485
|
+
_xinstanceof(Ecef9Tuple, ecef=ecef)
|
|
485
486
|
ltp = self
|
|
486
487
|
if ecef.datum != ltp.datum:
|
|
487
488
|
ecef = ecef.toDatum(ltp.datum)
|
|
488
|
-
|
|
489
|
+
n, kwds = _name2__(name_Xyz_kwds, _or_nameof=ecef)
|
|
490
|
+
x, y, z = self.M.rotate(ecef.xyz, *ltp._t0_xyz)
|
|
489
491
|
r = Local9Tuple(x, y, z, ecef.lat, ecef.lon, ecef.height,
|
|
490
|
-
ltp, ecef, None, name=
|
|
492
|
+
ltp, ecef, None, name=n)
|
|
491
493
|
if Xyz:
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
r = r.toXyz(Xyz=Xyz, **Xyz_kwds)
|
|
494
|
+
_xsubclassof(*_XyzLocals4, Xyz=Xyz) # Vector3d
|
|
495
|
+
r = r.toXyz(Xyz=Xyz, name=n, **kwds)
|
|
495
496
|
return r
|
|
496
497
|
|
|
497
498
|
@Property_RO
|
|
@@ -554,13 +555,14 @@ class LocalCartesian(_NamedBase):
|
|
|
554
555
|
'''(INTERNAL) Convert I{local} to geocentric/geodetic, like I{.reverse}.
|
|
555
556
|
|
|
556
557
|
@arg local: Local (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer} or L{Local9Tuple}).
|
|
557
|
-
@kwarg nine:
|
|
558
|
+
@kwarg nine: If C{True}, return a 9-, otherwise a 3-tuple (C{bool}).
|
|
558
559
|
@kwarg M: Include the rotation matrix (C{bool}).
|
|
559
560
|
|
|
560
561
|
@return: A I{geocentric} 3-tuple C{(x, y, z)} or if C{B{nine}=True},
|
|
561
562
|
an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)},
|
|
562
|
-
optionally including rotation matrix C{M}
|
|
563
|
+
optionally including rotation matrix C{M} otherwise C{None}.
|
|
563
564
|
'''
|
|
565
|
+
_xinstanceof(*_XyzLocals5, local=local)
|
|
564
566
|
t = self.M.unrotate(local.xyz, *self._t0_xyz)
|
|
565
567
|
if nine:
|
|
566
568
|
t = self.ecef.reverse(*t, M=M)
|
|
@@ -1065,8 +1067,30 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1065
1067
|
return t
|
|
1066
1068
|
|
|
1067
1069
|
|
|
1068
|
-
def
|
|
1069
|
-
|
|
1070
|
+
def _fov_2(**fov):
|
|
1071
|
+
# Half a field-of-view angle in C{degrees}.
|
|
1072
|
+
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
1073
|
+
if EPS < f < _90_0:
|
|
1074
|
+
return f
|
|
1075
|
+
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
1076
|
+
raise LocalError(txt=t, **fov)
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
def _toLocal(inst, ltp, Xyz, Xyz_kwds):
|
|
1080
|
+
'''(INTENRAL) Helper for C{CartesianBase.toLocal} and C{latLonBase.toLocal}.
|
|
1081
|
+
'''
|
|
1082
|
+
return _xLtp(ltp, inst._Ltp)._ecef2local(inst._ecef9, Xyz, Xyz_kwds)
|
|
1083
|
+
|
|
1084
|
+
|
|
1085
|
+
def _toLtp(inst, Ecef, ecef9, name):
|
|
1086
|
+
'''(INTENRAL) Helper for C{CartesianBase.toLtp} and C{latLonBase.toLtp}.
|
|
1087
|
+
'''
|
|
1088
|
+
return inst._Ltp if Ecef in (None, inst.Ecef) and not name else \
|
|
1089
|
+
Ltp(ecef9, ecef=Ecef(inst.datum), name=inst._name__(name))
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
|
|
1093
|
+
'''Convert an attitude pose into a (3-D) direction vector.
|
|
1070
1094
|
|
|
1071
1095
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees}), negative down
|
|
1072
1096
|
(clockwise rotation along and around the x-axis).
|
|
@@ -1074,27 +1098,41 @@ def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **Vector_kwds):
|
|
|
1074
1098
|
(counter-clockwise rotation along and around the z-axis).
|
|
1075
1099
|
@kwarg roll: Roll, bank (C{degrees}), positive to the right and down
|
|
1076
1100
|
(clockwise rotation along and around the y-axis).
|
|
1101
|
+
@kwarg Vector: Class to return the direction vector (C{Cartesian},
|
|
1102
|
+
L{Vector3d} or C{Vector3Tuple}) or C{None}.
|
|
1103
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
1104
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
1105
|
+
C{B{Vector} is None}.
|
|
1077
1106
|
|
|
1078
1107
|
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
1079
1108
|
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
1080
1109
|
|
|
1110
|
+
@raise AttitudeError: Invalid B{C{tilt}}, B{C{yaw}} or B{C{roll}}.
|
|
1111
|
+
|
|
1112
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
1113
|
+
|
|
1081
1114
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}
|
|
1082
|
-
and function L{pygeodesy.hartzell} argument C{los}.
|
|
1115
|
+
and function L{pygeodesy.hartzell} argument C{los}, Line-Of-Sight.
|
|
1083
1116
|
'''
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1117
|
+
v = Attitude4Tuple(_0_0, tilt, yaw, roll).tyr3d
|
|
1118
|
+
if Vector is not type(v):
|
|
1119
|
+
n, kwds = _name2__(name_Vector_kwds, name__=tyr3d)
|
|
1120
|
+
v = Vector3Tuple(v.x, v.y, v.z, name=n) if Vector is None else \
|
|
1121
|
+
Vector(v.x, v.y, v.z, name=n, **kwds)
|
|
1122
|
+
elif name_Vector_kwds:
|
|
1123
|
+
n, _ = _name2__(name_Vector_kwds)
|
|
1124
|
+
if n:
|
|
1125
|
+
v = v.copy(name=n)
|
|
1126
|
+
return v
|
|
1088
1127
|
|
|
1089
1128
|
|
|
1090
1129
|
def _xLtp(ltp, *dflt):
|
|
1091
|
-
'''(INTERNAL) Validate B{C{ltp}}.
|
|
1130
|
+
'''(INTERNAL) Validate B{C{ltp}} or ist B{C{dflt}}.
|
|
1092
1131
|
'''
|
|
1093
1132
|
if dflt and ltp is None:
|
|
1094
1133
|
ltp = dflt[0]
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
raise _TypesError(_ltp_, ltp, Ltp, LocalCartesian)
|
|
1134
|
+
_xinstanceof(Ltp, LocalCartesian, ltp=ltp)
|
|
1135
|
+
return ltp
|
|
1098
1136
|
|
|
1099
1137
|
# **) MIT License
|
|
1100
1138
|
#
|