pygeodesy 24.6.1__py2.py3-none-any.whl → 24.6.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.
Files changed (89) hide show
  1. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.6.24.dist-info/RECORD +117 -0
  3. pygeodesy/__init__.py +33 -32
  4. pygeodesy/albers.py +2 -2
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/auxAngle.py +40 -39
  7. pygeodesy/auxilats/auxDLat.py +3 -2
  8. pygeodesy/auxilats/auxLat.py +16 -18
  9. pygeodesy/auxilats/auxily.py +1 -1
  10. pygeodesy/azimuthal.py +10 -10
  11. pygeodesy/basics.py +9 -1
  12. pygeodesy/booleans.py +53 -66
  13. pygeodesy/cartesianBase.py +143 -155
  14. pygeodesy/css.py +14 -18
  15. pygeodesy/datums.py +6 -6
  16. pygeodesy/deprecated/__init__.py +1 -1
  17. pygeodesy/deprecated/classes.py +16 -2
  18. pygeodesy/deprecated/datum.py +3 -3
  19. pygeodesy/deprecated/functions.py +6 -8
  20. pygeodesy/dms.py +23 -27
  21. pygeodesy/ecef.py +49 -55
  22. pygeodesy/elevations.py +4 -4
  23. pygeodesy/ellipsoidalBase.py +28 -70
  24. pygeodesy/ellipsoidalBaseDI.py +19 -23
  25. pygeodesy/ellipsoidalExact.py +3 -3
  26. pygeodesy/ellipsoidalGeodSolve.py +15 -23
  27. pygeodesy/ellipsoidalKarney.py +37 -60
  28. pygeodesy/ellipsoidalNvector.py +44 -50
  29. pygeodesy/ellipsoidalVincenty.py +11 -14
  30. pygeodesy/ellipsoids.py +107 -101
  31. pygeodesy/errors.py +101 -49
  32. pygeodesy/etm.py +32 -44
  33. pygeodesy/formy.py +55 -58
  34. pygeodesy/frechet.py +20 -23
  35. pygeodesy/fsums.py +4 -4
  36. pygeodesy/gars.py +3 -4
  37. pygeodesy/geodesici.py +909 -0
  38. pygeodesy/geodesicw.py +11 -13
  39. pygeodesy/geodesicx/__init__.py +4 -4
  40. pygeodesy/geodesicx/gx.py +18 -28
  41. pygeodesy/geodesicx/gxbases.py +20 -8
  42. pygeodesy/geodesicx/gxline.py +16 -22
  43. pygeodesy/geodsolve.py +102 -34
  44. pygeodesy/geohash.py +39 -60
  45. pygeodesy/geoids.py +28 -37
  46. pygeodesy/hausdorff.py +21 -23
  47. pygeodesy/heights.py +15 -28
  48. pygeodesy/internals.py +19 -12
  49. pygeodesy/interns.py +4 -10
  50. pygeodesy/iters.py +2 -2
  51. pygeodesy/karney.py +20 -4
  52. pygeodesy/ktm.py +13 -16
  53. pygeodesy/latlonBase.py +202 -191
  54. pygeodesy/lazily.py +96 -59
  55. pygeodesy/lcc.py +29 -32
  56. pygeodesy/ltp.py +43 -24
  57. pygeodesy/ltpTuples.py +190 -183
  58. pygeodesy/mgrs.py +35 -9
  59. pygeodesy/named.py +106 -72
  60. pygeodesy/namedTuples.py +43 -14
  61. pygeodesy/nvectorBase.py +23 -27
  62. pygeodesy/osgr.py +9 -9
  63. pygeodesy/points.py +7 -7
  64. pygeodesy/rhumb/__init__.py +1 -1
  65. pygeodesy/rhumb/aux_.py +5 -5
  66. pygeodesy/rhumb/bases.py +30 -31
  67. pygeodesy/rhumb/ekx.py +3 -4
  68. pygeodesy/rhumb/solve.py +8 -61
  69. pygeodesy/solveBase.py +22 -19
  70. pygeodesy/sphericalBase.py +26 -21
  71. pygeodesy/sphericalNvector.py +13 -13
  72. pygeodesy/sphericalTrigonometry.py +86 -97
  73. pygeodesy/streprs.py +8 -36
  74. pygeodesy/trf.py +3 -3
  75. pygeodesy/triaxials.py +117 -91
  76. pygeodesy/units.py +229 -321
  77. pygeodesy/unitsBase.py +116 -108
  78. pygeodesy/ups.py +26 -31
  79. pygeodesy/utily.py +12 -11
  80. pygeodesy/utm.py +35 -40
  81. pygeodesy/utmups.py +43 -46
  82. pygeodesy/utmupsBase.py +9 -10
  83. pygeodesy/vector3d.py +59 -62
  84. pygeodesy/vector3dBase.py +17 -15
  85. pygeodesy/webmercator.py +19 -21
  86. pygeodesy/wgrs.py +18 -20
  87. PyGeodesy-24.6.1.dist-info/RECORD +0 -116
  88. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/WHEEL +0 -0
  89. {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.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, _areaOf_, _attribute_, _by_, _COLONSPACE_, \
37
- _COMMASPACE_, _doesn_t_exist_, _DOT_, _enabled_, \
38
- _EQUALSPACED_, _from_, _HASH_, _immutable_, \
39
- _isclockwise_, _ispolar_, _line_, _module_, \
40
- _no_, _NorthPole_, _not_, _or_, _pygeodesy_, \
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
- _str_x = str(x)
51
-
52
- def import_module(name, *package):
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
- _dunder_package_ = '__package__'
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
- _lazily_imported__ = _SPACE_(_HASH_, _lazily_, 'imported', NN)
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 = None # see @var isLazy in .__init__
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), *_sub_packages)
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(_attrof, attr))
182
+ t += tuple(map(_getattrof, attr))
189
183
  return t
190
184
 
191
185
 
@@ -289,8 +283,9 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
289
283
  fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
290
284
  'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
291
285
  gars=_i('Garef', 'GARSError'),
286
+ geodesici=_i('Intersector', 'Intersector5Tuple', 'XDist'),
292
287
  geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
293
- geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules, see _sub_packages
288
+ geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
294
289
  'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
295
290
  geodsolve=_i('GeodesicSolve', 'GeodesicLineSolve', 'GeodSolve12Tuple'),
296
291
  geohash=_i('Geohash', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple'),
@@ -340,11 +335,11 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
340
335
  'Reverse4Tuple', 'Triangle7Tuple', 'Triangle8Tuple', 'Trilaterate5Tuple',
341
336
  'UtmUps2Tuple', 'UtmUps5Tuple', 'UtmUps8Tuple', 'UtmUpsLatLon5Tuple',
342
337
  'Vector2Tuple', 'Vector3Tuple', 'Vector4Tuple'),
343
- nvectorBase=_i(_NorthPole_, _SouthPole_),
338
+ nvectorBase=_i('NorthPole', 'SouthPole'),
344
339
  osgr=_i('Osgr', 'OSGRError', 'parseOSGR', 'toOsgr'),
345
340
  points=_i('LatLon_', 'LatLon2psxy', 'Numpy2LatLon', 'Shape2Tuple', 'Tuple2LatLon',
346
- _areaOf_, 'boundsOf', 'centroidOf', 'fractional',
347
- _isclockwise_, 'isconvex', 'isconvex_', 'isenclosedBy', _ispolar_,
341
+ 'areaOf', 'boundsOf', 'centroidOf', 'fractional',
342
+ 'isclockwise', 'isconvex', 'isconvex_', 'isenclosedBy', 'ispolar',
348
343
  'luneOf', 'nearestOn5', 'perimeterOf', 'quadOf'),
349
344
  props=_i('Property', 'Property_RO', 'property_RO', 'property_doc_',
350
345
  'deprecated_class', 'deprecated_function', 'deprecated_method',
@@ -373,9 +368,9 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
373
368
  units=_i('Band', 'Bearing', 'Bearing_', 'Bool',
374
369
  'Degrees', 'Degrees_', 'Degrees2', 'Distance', 'Distance_', 'Easting', 'Epoch',
375
370
  'Feet', 'FIx', 'Float_', 'Height', 'Height_', 'HeightX', 'Int_',
376
- 'Lam', 'Lam_', 'Lat', 'Lat_', 'Lon', 'Lon_',
371
+ 'Lam', 'Lamd', 'Lat', 'Lat_', 'Lon', 'Lon_',
377
372
  'Meter', 'Meter_', 'Meter2', 'Meter3', 'Northing', 'Number_',
378
- 'Phi', 'Phi_', 'Precision_', 'Radians', 'Radians_', 'Radians2',
373
+ 'Phi', 'Phid', 'Precision_', 'Radians', 'Radians_', 'Radians2',
379
374
  'Radius_', 'Scalar', 'Scalar_', 'Zone'),
380
375
  unitsBase=_i('Float', 'Int', 'Radius', 'Str'),
381
376
  ups=_i('Ups', 'UPSError', 'parseUPS5', 'toUps8', 'upsZoneBand5'),
@@ -412,13 +407,13 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
412
407
  deprecated_bases=_i('LatLonHeightBase', 'points2'),
413
408
  deprecated_classes=_i('ClipCS3Tuple', 'EasNorExact4Tuple', 'EcefCartesian', 'Fn_rt',
414
409
  'HeightIDW', 'HeightIDW2', 'HeightIDW3', 'Helmert7Tuple',
415
- 'LatLonExact4Tuple', 'NearestOn4Tuple', 'Ned3Tuple',
416
- 'RefFrameError', 'Rhumb7Tuple', 'RhumbOrder2Tuple',
410
+ 'Lam_', 'LatLonExact4Tuple', 'NearestOn4Tuple', 'Ned3Tuple',
411
+ 'Phi_', 'RefFrameError', 'Rhumb7Tuple', 'RhumbOrder2Tuple',
417
412
  'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple'),
418
413
  deprecated_consterns=_i('EPS1_2', 'MANTIS', 'OK'),
419
414
  deprecated_datum=_i('Curvature2Tuple', 'Datum', 'Ellipsoid', 'Transform', # assert
420
415
  'Datums', 'Ellipsoids', 'Transforms',
421
- 'R_M', 'R_MA', 'R_MB', 'R_KM', 'R_NM', 'R_SM', 'R_FM', 'R_VM'),
416
+ 'R_FM', 'R_KM', 'R_M', 'R_MA', 'R_MB', 'R_NM', 'R_SM', 'R_VM'),
422
417
  deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ...
423
418
  'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ... ellipsoidal, spherical flavors
424
419
  'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular_', 'equirectangular3',
@@ -432,7 +427,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
432
427
  deprecated_nvector=_i('LatLonNvectorBase', 'Nvector', 'sumOf', 'NorthPole', 'SouthPole'),)
433
428
 
434
429
 
435
- class _ALL_MODS(_internals._ALL_MODS_Base):
430
+ class _ALL_MODS(_internals._MODS_Base):
436
431
  '''(INTERNAL) Memoized import of any L{pygeodesy} module.
437
432
  '''
438
433
  def __getattr__(self, name):
@@ -474,7 +469,7 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
474
469
  return v
475
470
 
476
471
  def getmodule(self, name, parent=_pygeodesy_):
477
- '''Get a C{pygeodesy} module.
472
+ '''Get a C{pygeodesy} module or the C{__main__}.
478
473
 
479
474
  @arg name: Un/qualified module name (C{str}).
480
475
 
@@ -482,12 +477,36 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
482
477
 
483
478
  @raise ImportError: Importing module B{C{name}} failed.
484
479
  '''
485
- if _headof(name) != parent:
480
+ if _headof(name) != parent and not _dunder_ismain(name):
486
481
  name = _DOT_(parent, name)
487
482
  try:
488
483
  return _sys.modules[name]
489
484
  except KeyError:
490
- return import_module(name, parent)
485
+ return _getmodule(name, parent)
486
+
487
+ def into(self, **mod_dunder_name_):
488
+ '''Lazily import module C{mod} into module C{_dunder_name_}
489
+ and set C{_dunder_name_._mod} to module C{mod}, I{once}.
490
+ '''
491
+ class _Into(object):
492
+
493
+ def __getattr__(unused, name):
494
+ mod, dun = self.errors._xkwds_item2(mod_dunder_name_)
495
+ _mod = _UNDER_(NN, mod)
496
+ d = self.getmodule(dun) # '__main__' OK
497
+ i = _getattribute(d, _mod, dun)
498
+ assert isinstance(i, _Into)
499
+ m = self.getmodule(mod)
500
+ setattr(d, _mod, m) # overwrite C{d._mod}
501
+ return getattr(m, name)
502
+
503
+ return _Into()
504
+
505
+ # @_Property_RO
506
+ # def _isBoolean(self):
507
+ # '''(INTERNAL) Get function C(.booleans.isBoolean}, I{once}.
508
+ # '''
509
+ # return self.booleans.isBoolean
491
510
 
492
511
  def items(self): # no module named 'items'
493
512
  '''Yield the modules imported so far.
@@ -500,7 +519,7 @@ class _ALL_MODS(_internals._ALL_MODS_Base):
500
519
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
501
520
 
502
521
  __all__ = _ALL_LAZY.lazily
503
- __version__ = '24.05.15'
522
+ __version__ = '24.06.19'
504
523
 
505
524
 
506
525
  def _ALL_OTHER(*objs):
@@ -565,11 +584,34 @@ def _all_missing2(_all_):
565
584
  (_DOT_(_pygeodesy_, _dunder_all_), _diff(_alzy.keys(), _all_)))
566
585
 
567
586
 
568
- def _attrof(attr_as): # .testDeprecated
587
+ def _getattribute(m, name, mod=_pygeodesy_):
588
+ '''(INTERNAL) Get attr C{m.name}.
589
+ '''
590
+ try:
591
+ return getattr(m, name)
592
+ except AttributeError:
593
+ name = _DOT_(mod, name)
594
+ # <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
595
+ raise LazyAttributeError(_no_(_attribute_), txt=name)
596
+
597
+
598
+ def _getattrof(attr_as): # .testDeprecated
599
+ '''(INTERNAL) Get the C{"as name"} or C{"name"} of a lazy entry.
600
+ '''
569
601
  a_, _, as_ = attr_as.partition(__as__)
570
602
  return as_ or a_.rstrip(_DOT_)
571
603
 
572
604
 
605
+ def _getmodule(name, *parent):
606
+ '''(INTERNAL) Wrapper for C{import_module}.
607
+ '''
608
+ try:
609
+ return import_module(name, parent)
610
+ except ImportError:
611
+ # <https://GitHub.com/mrJean1/PyGeodesy/issues/76>
612
+ raise LazyImportError(_no_(_module_), txt=name)
613
+
614
+
573
615
  # def _lazy_attributes(_dunder_name_):
574
616
  # '''(INTERNAL) Return a function to C{B{__name__}.__getattr__(attr)}
575
617
  # on lazily imported modules and sub-modules.
@@ -615,17 +657,19 @@ def _lazy_import2(pack): # MCCABE 14
615
657
  U{PEP 562<https://www.Python.org/dev/peps/pep-0562>} and the
616
658
  U{new way<https://Snarky.Ca/lazy-importing-in-python-3-7/>}.
617
659
  '''
660
+ _DOT_ = _interns._DOT_
661
+ _SPACE_ = _interns._SPACE_
662
+
618
663
  if pack != _pygeodesy_ or _unlazy: # Python 3.7+
619
664
  t = _no_(_DOT_(pack, _dunder_nameof(_lazy_import2))) # PYCHOK no cover
620
665
  raise LazyImportError(t, txt=_Pythonarchine(sep=_SPACE_))
621
666
 
622
- package, parent = _lazy_init2(pack) # _pygeodesy_
623
-
624
- subpacks = set((parent, NN) + tuple(
625
- _DOT_(parent, s) for s in _sub_packages))
626
- MISSING = object() # DON'T interns.MISSING!
627
- imports = _all_imports()
628
- deprecates = _all_deprecates()
667
+ package, parent = _lazy_init2(pack) # _pygeodesy_
668
+ sub_packages = set((parent, NN) + tuple(
669
+ _DOT_(parent, s) for s in _SUB_PACKAGES))
670
+ imports = _all_imports()
671
+ deprecates = _all_deprecates()
672
+ _dunder_package_ = '__package__'
629
673
 
630
674
  def __getattr__(name): # __getattr__ only for Python 3.7+
631
675
  # only called once for each undefined pygeodesy attribute
@@ -638,21 +682,12 @@ def _lazy_import2(pack): # MCCABE 14
638
682
  mod, _, attr = mod[:-1].rpartition(_DOT_)
639
683
  else: # from mod import name
640
684
  attr = name
641
- try:
642
- t = _DOT_(pack, mod)
643
- v = import_module(t, parent)
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
685
+ v = _getmodule(_DOT_(pack, mod), parent)
686
+ t = getattr(v, _dunder_package_, None)
687
+ if t not in sub_packages: # invalid module package
649
688
  raise LazyImportError(_DOT_(mod, _dunder_package_), t)
650
- if attr: # get the attribute
651
- v = getattr(v, attr, MISSING)
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)
689
+ if attr: # get mod.attr
690
+ v = _getattribute(v, attr, mod)
656
691
 
657
692
  elif name in (_dunder_all_,): # XXX _dunder_dir_, _dunder_members_?
658
693
  v = _ALL_INIT + tuple(imports.keys())
@@ -663,9 +698,9 @@ def _lazy_import2(pack): # MCCABE 14
663
698
 
664
699
  setattr(package, name, v) # package.__dict__[name] = val
665
700
  if isLazy > 1:
666
- t = NN(_lazily_imported__, _DOT_(parent, name))
701
+ t = _SPACE_(_lazily_imported_, _DOT_(parent, name))
667
702
  if mod and _tailof(mod) != name:
668
- t = NN(t, _from_DOT__, mod)
703
+ t = _SPACE_(t, _from_, _DOT_(NN, mod))
669
704
  if isLazy > 2:
670
705
  try: # see C{_caller3}
671
706
  _, f, s = _caller3(2)
@@ -827,6 +862,8 @@ def _lazy_module(name): # overwritten by _lazy_import2
827
862
 
828
863
  # del _i, _i0
829
864
 
865
+ # _ = _ALL_MODS.errors # force import pygeodesy.errors
866
+
830
867
  if _dunder_ismain(__name__): # PYCHOK no cover
831
868
 
832
869
  from timeit import timeit
pygeodesy/lcc.py CHANGED
@@ -41,14 +41,14 @@ from pygeodesy.namedTuples import EasNor3Tuple, LatLonDatum3Tuple, \
41
41
  LatLon2Tuple, _LL4Tuple, PhiLam2Tuple
42
42
  from pygeodesy.props import deprecated_method, Property, Property_RO, _update_all
43
43
  from pygeodesy.streprs import Fmt, _fstrENH2, _xzipairs
44
- from pygeodesy.units import Easting, Height, _heigHt, Lam_, Northing, Phi_, \
44
+ from pygeodesy.units import Easting, Height, _heigHt, Lamd, Northing, Phid, \
45
45
  Scalar_
46
46
  from pygeodesy.utily import atan1, degrees90, degrees180, sincos2, tanPI_2_2
47
47
 
48
48
  from math import atan, fabs, log, radians, sin, sqrt
49
49
 
50
50
  __all__ = _ALL_LAZY.lcc
51
- __version__ = '24.05.24'
51
+ __version__ = '24.06.24'
52
52
 
53
53
  _E0_ = 'E0'
54
54
  _N0_ = 'N0'
@@ -107,8 +107,8 @@ class Conic(_NamedEnumItem):
107
107
  _xinstanceof(_LLEB, latlon0=latlon0)
108
108
  self._phi0, self._lam0 = latlon0.philam
109
109
 
110
- self._par1 = Phi_(par1=par1)
111
- self._par2 = self._par1 if par2 is None else Phi_(par2=par2)
110
+ self._par1 = Phid(par1=par1)
111
+ self._par2 = self._par1 if par2 is None else Phid(par2=par2)
112
112
 
113
113
  if k0 != 1:
114
114
  self._k0 = Scalar_(k0=k0)
@@ -117,7 +117,7 @@ class Conic(_NamedEnumItem):
117
117
  if N0:
118
118
  self._N0 = Easting(N0=N0, falsed=True)
119
119
  if opt3:
120
- self._opt3 = Lam_(opt3=opt3)
120
+ self._opt3 = Lamd(opt3=opt3)
121
121
 
122
122
  self.toDatum(latlon0.datum)._dup2(self)
123
123
  self._register(Conics, name)
@@ -278,20 +278,19 @@ class Conic(_NamedEnumItem):
278
278
 
279
279
  return c
280
280
 
281
- def toStr(self, prec=8, name=NN, **unused): # PYCHOK expected
281
+ def toStr(self, prec=8, **name): # PYCHOK expected
282
282
  '''Return this conic as a string.
283
283
 
284
284
  @kwarg prec: Number of (decimal) digits, unstripped (C{int}).
285
- @kwarg name: Overriding name (C{str}) or C{None} to exclude
286
- this conic's name.
285
+ @kwarg name: Overriding C{B{name}=NN} (C{str}) or C{None} to
286
+ exclude this conic's name.
287
287
 
288
288
  @return: Conic attributes (C{str}).
289
289
  '''
290
- a = [name, prec, _lat0_, _lon0_, _par1_, _par2_,
291
- _E0_, _N0_, _k0_, _SP_]
290
+ a = [_lat0_, _lon0_, _par1_, _par2_, _E0_, _N0_, _k0_, _SP_]
292
291
  if self._SP == 1:
293
292
  _ = a.pop(a.index(_par2_))
294
- return self._instr(datum=self.datum, *a)
293
+ return self._instr(datum=self.datum, prec=prec, *a, **name)
295
294
 
296
295
  def _dup2(self, c):
297
296
  '''(INTERNAL) Copy this conic to C{c}.
@@ -454,7 +453,7 @@ class Lcc(_NamedBase):
454
453
  #
455
454
  # kwds = _xkwds(e_n_h_conic, e=self.easting, n=self.northing,
456
455
  # h=self.height, conic=self.conic,
457
- # name=name or self.name)
456
+ # name=self._name__(name))
458
457
  # args, kwds = _args_kwds(**kwds)
459
458
  # return self.__class__(*args, **kwds) # .classof
460
459
 
@@ -537,22 +536,21 @@ class Lcc(_NamedBase):
537
536
  def toLatLon(self, LatLon=None, datum=None, height=None, **LatLon_kwds):
538
537
  '''Convert this L{Lcc} to an (ellipsoidal) geodetic point.
539
538
 
540
- @kwarg LatLon: Optional, ellipsoidal class to return the
541
- geodetic point (C{LatLon}) or C{None}.
542
- @kwarg datum: Optional datum to use, otherwise use this
543
- B{C{Lcc}}'s conic.datum (L{Datum}, L{Ellipsoid},
544
- L{Ellipsoid2} or L{a_f2Tuple}).
545
- @kwarg height: Optional height for the point, overriding
546
- the default height (C{meter}).
547
- @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
548
- arguments, ignored if C{B{LatLon} is None}.
539
+ @kwarg LatLon: Optional, ellipsoidal class to return the geodetic
540
+ point (C{LatLon}) or C{None}.
541
+ @kwarg datum: Optional datum to use, otherwise use this B{C{Lcc}}'s
542
+ conic.datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or
543
+ L{a_f2Tuple}).
544
+ @kwarg height: Optional height for the point, overriding the default height
545
+ (C{meter}).
546
+ @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments,
547
+ ignored if C{B{LatLon} is None}.
549
548
 
550
- @return: The point (B{C{LatLon}}) or a
551
- L{LatLon4Tuple}C{(lat, lon, height, datum)}
552
- if B{C{LatLon}} is C{None}.
549
+ @return: The point (B{C{LatLon}}) or if C{B{LatLon} is None}, a
550
+ L{LatLon4Tuple}C{(lat, lon, height, datum)}.
553
551
 
554
- @raise TypeError: If B{C{LatLon}} or B{C{datum}} is
555
- not ellipsoidal or not valid.
552
+ @raise TypeError: If B{C{LatLon}} or B{C{datum}} is not ellipsoidal or
553
+ not valid.
556
554
  '''
557
555
  if LatLon:
558
556
  _xsubclassof(_LLEB, LatLon=LatLon)
@@ -622,13 +620,12 @@ def toLcc(latlon, conic=Conics.WRF_Lb, height=None, Lcc=Lcc,
622
620
  @kwarg height: Optional height for the point, overriding the
623
621
  default height (C{meter}).
624
622
  @kwarg Lcc: Class to return the I{Lambert} location (L{Lcc}).
625
- @kwarg name_Lcc_kwds: Optional C{B{name}=NN} (C{str}) for the
626
- location and optional, additional B{C{Lcc}} keyword
627
- arguments, ignored if B{C{Lcc}} is C{None}.
623
+ @kwarg name_Lcc_kwds: Optional C{B{name}=NN} (C{str}) and optional,
624
+ additional B{C{Lcc}} keyword arguments, ignored if
625
+ B{C{Lcc} is None}.
628
626
 
629
- @return: The I{Lambert} location (L{Lcc}) or an
630
- L{EasNor3Tuple}C{(easting, northing, height)} if
631
- C{B{Lcc} is None}.
627
+ @return: The I{Lambert} location (L{Lcc}) or if C{B{Lcc} is None},
628
+ an L{EasNor3Tuple}C{(easting, northing, height)}.
632
629
 
633
630
  @raise TypeError: If B{C{latlon}} is not ellipsoidal.
634
631
  '''
pygeodesy/ltp.py CHANGED
@@ -13,18 +13,20 @@ 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, map1, map2, _xsubclassof # .datums
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, _xinstanceof
21
- from pygeodesy.ecef import _EcefBase, EcefKarney, _llhn4, _xyzn4
22
- from pygeodesy.errors import _NotImplementedError, _TypesError, _ValueError, \
23
- _xattr, _xkwds, _xkwds_get, _xkwds_pop2
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_, _ltp_, _name_, _too_
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, \
@@ -42,7 +44,7 @@ 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.05.31'
47
+ __version__ = '24.06.11'
46
48
 
47
49
  _height0_ = _height_ + _0_
48
50
  _narrow_ = 'narrow'
@@ -152,7 +154,7 @@ class Attitude(_NamedBase):
152
154
  additional B{C{Vector}} keyword arguments, ignored if
153
155
  C{B{Vector} is None}.
154
156
 
155
- @return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
157
+ @return: A named B{C{Vector}} instance or if C{B{Vector} is None},
156
158
  a named L{Vector3Tuple}C{(x, y, z)}.
157
159
 
158
160
  @raise AttitudeError: Invalid B{C{x_xyz}}, B{C{y}} or B{C{z}}.
@@ -417,13 +419,12 @@ class LocalCartesian(_NamedBase):
417
419
  @kwarg latlonh0: The (geodetic) origin (C{LatLon}, L{LatLon4Tuple}, L{Ltp}
418
420
  L{LocalCartesian} or L{Ecef9Tuple}) or the C{scalar}
419
421
  latitude of the (goedetic) origin (C{degrees}).
420
- @kwarg lon0: Longitude of the (goedetic) origin (C{degrees}) for C{scalar}
421
- B{C{latlonh0}}, ignored otherwise.
422
+ @kwarg lon0: Longitude of the (goedetic) origin (C{degrees}), required if
423
+ B{C{latlonh0}} is C{scalar}, ignored otherwise.
422
424
  @kwarg height0: Optional height (C{meter}, conventionally) at the (goedetic)
423
425
  origin perpendicular to and above (or below) the ellipsoid's
424
- surface and for C{scalar} B{C{latlonh0}}, ignored otherwise.
425
- @kwarg ecef: An ECEF converter (L{EcefKarney} I{only}) for C{scalar}
426
- B{C{latlonh0}}, ignored otherwise.
426
+ surface, like B{C{lon0}}.
427
+ @kwarg ecef: An ECEF converter (L{EcefKarney} I{only}), like B{C{lon0}}.
427
428
  @kwarg lon00_name: Optional C{B{name}=NN} (C{str}) and keyword argument
428
429
  C{B{lon00}=B{lon0}} for the arbitrary I{polar} longitude
429
430
  (C{degrees}), see method C{reverse} and property C{lon00}
@@ -480,6 +481,7 @@ class LocalCartesian(_NamedBase):
480
481
 
481
482
  @raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
482
483
  '''
484
+ _xinstanceof(Ecef9Tuple, ecef=ecef)
483
485
  ltp = self
484
486
  if ecef.datum != ltp.datum:
485
487
  ecef = ecef.toDatum(ltp.datum)
@@ -557,8 +559,9 @@ class LocalCartesian(_NamedBase):
557
559
 
558
560
  @return: A I{geocentric} 3-tuple C{(x, y, z)} or if C{B{nine}=True},
559
561
  an L{Ecef9Tuple}C{(x, y, z, lat, lon, height, C, M, datum)},
560
- optionally including rotation matrix C{M} or C{None}.
562
+ optionally including rotation matrix C{M} otherwise C{None}.
561
563
  '''
564
+ _xinstanceof(*_XyzLocals5, local=local)
562
565
  t = self.M.unrotate(local.xyz, *self._t0_xyz)
563
566
  if nine:
564
567
  t = self.ecef.reverse(*t, M=M)
@@ -1072,6 +1075,19 @@ def _fov_2(**fov):
1072
1075
  raise LocalError(txt=t, **fov)
1073
1076
 
1074
1077
 
1078
+ def _toLocal(inst, ltp, Xyz, Xyz_kwds):
1079
+ '''(INTENRAL) Helper for C{CartesianBase.toLocal} and C{latLonBase.toLocal}.
1080
+ '''
1081
+ return _xLtp(ltp, inst._Ltp)._ecef2local(inst._ecef9, Xyz, Xyz_kwds)
1082
+
1083
+
1084
+ def _toLtp(inst, Ecef, ecef9, name):
1085
+ '''(INTENRAL) Helper for C{CartesianBase.toLtp} and C{latLonBase.toLtp}.
1086
+ '''
1087
+ return inst._Ltp if Ecef in (None, inst.Ecef) and not name else \
1088
+ Ltp(ecef9, ecef=Ecef(inst.datum), name=inst._name__(name))
1089
+
1090
+
1075
1091
  def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
1076
1092
  '''Convert an attitude pose into a (3-D) direction vector.
1077
1093
 
@@ -1087,7 +1103,7 @@ def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
1087
1103
  additional B{C{Vector}} keyword arguments, ignored if
1088
1104
  C{B{Vector} is None}.
1089
1105
 
1090
- @return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
1106
+ @return: A named B{C{Vector}} instance or if C{B{Vector} is None},
1091
1107
  a named L{Vector3Tuple}C{(x, y, z)}.
1092
1108
 
1093
1109
  @raise AttitudeError: Invalid B{C{tilt}}, B{C{yaw}} or B{C{roll}}.
@@ -1097,22 +1113,25 @@ def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
1097
1113
  @see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}
1098
1114
  and function L{pygeodesy.hartzell} argument C{los}, Line-Of-Sight.
1099
1115
  '''
1100
- d = Attitude4Tuple(_0_0, tilt, yaw, roll).tyr3d
1101
- if Vector is not type(d):
1116
+ v = Attitude4Tuple(_0_0, tilt, yaw, roll).tyr3d
1117
+ if Vector is not type(v):
1102
1118
  n, kwds = _name2__(name_Vector_kwds, name__=tyr3d)
1103
- d = Vector3Tuple(d.x, d.y, d.z, name=n) if Vector is None else \
1104
- Vector(d.x, d.y, d.z, name=n, **kwds)
1105
- return d
1119
+ v = Vector3Tuple(v.x, v.y, v.z, name=n) if Vector is None else \
1120
+ Vector(v.x, v.y, v.z, name=n, **kwds)
1121
+ elif name_Vector_kwds:
1122
+ n, _ = _name2__(name_Vector_kwds)
1123
+ if n:
1124
+ v = v.copy(name=n)
1125
+ return v
1106
1126
 
1107
1127
 
1108
1128
  def _xLtp(ltp, *dflt):
1109
- '''(INTERNAL) Validate B{C{ltp}}.
1129
+ '''(INTERNAL) Validate B{C{ltp}} or ist B{C{dflt}}.
1110
1130
  '''
1111
1131
  if dflt and ltp is None:
1112
1132
  ltp = dflt[0]
1113
- if isinstance(ltp, (LocalCartesian, Ltp)):
1114
- return ltp
1115
- raise _TypesError(_ltp_, ltp, Ltp, LocalCartesian)
1133
+ _xinstanceof(Ltp, LocalCartesian, ltp=ltp)
1134
+ return ltp
1116
1135
 
1117
1136
  # **) MIT License
1118
1137
  #