pygeodesy 24.7.7__py2.py3-none-any.whl → 24.8.4__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/lazily.py CHANGED
@@ -31,8 +31,7 @@ from pygeodesy import internals as _internals, interns as _interns, \
31
31
  _isfrozen # DON'T _lazy_import2
32
32
  # from pygeodesy.errors import _error_init, _xkwds_item2 # _ALL_MODS
33
33
  from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_ismain, \
34
- _headof, _osversion2, printf, _Pythonarchine, \
35
- _tailof # _Property_RO
34
+ _headof, printf, _Pythonarchine, _tailof # _Property_RO
36
35
  from pygeodesy.interns import NN, _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, \
37
36
  _doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
38
37
  _HASH_, _immutable_, _line_, _module_, _no_, _not_, \
@@ -284,13 +283,13 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
284
283
  fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
285
284
  'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
286
285
  gars=_i('Garef', 'GARSError'),
287
- geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Middle5Tuple',
288
- 'Intersector', 'Intersector5Tuple', 'XDict'),
286
+ geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Intersect7Tuple',
287
+ 'Intersector', 'Intersector5Tuple', 'Middle5Tuple', 'XDict'),
289
288
  geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
290
289
  geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
291
290
  'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
292
291
  geodsolve=_i('GeodesicSolve', 'GeodesicLineSolve', 'GeodSolve12Tuple'),
293
- geohash=_i('Geohash', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple'),
292
+ geohash=_i('Geohash', 'Geohashed', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple', 'Sizes3Tuple'),
294
293
  geoids=_i('GeoidError', 'GeoidG2012B', 'GeoidKarney', 'GeoidPGM', 'egmGeoidHeights',
295
294
  'PGMError', 'GeoidHeight5Tuple'),
296
295
  hausdorff=_i('Hausdorff', 'HausdorffDegrees', 'HausdorffError', 'HausdorffRadians',
@@ -343,7 +342,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
343
342
  'areaOf', 'boundsOf', 'centroidOf', 'fractional',
344
343
  'isclockwise', 'isconvex', 'isconvex_', 'isenclosedBy', 'ispolar',
345
344
  'luneOf', 'nearestOn5', 'perimeterOf', 'quadOf'),
346
- props=_i('Property', 'Property_RO', 'property_RO', 'property_doc_',
345
+ props=_i('Property', 'Property_RO', 'property_doc_',
346
+ 'property_RO', 'property_ROnce', 'property_ROver',
347
347
  'deprecated_class', 'deprecated_function', 'deprecated_method',
348
348
  'deprecated_Property_RO', 'deprecated_property_RO', 'DeprecationWarnings'),
349
349
  resections=_i('Collins5Tuple', 'ResectionError', 'Survey3Tuple', 'Tienstra7Tuple',
@@ -367,7 +367,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
367
367
  triaxials=_i('BetaOmega2Tuple', 'BetaOmega3Tuple', 'Jacobi2Tuple',
368
368
  'JacobiConformal', 'JacobiConformalSpherical',
369
369
  'Triaxial', 'Triaxial_', 'TriaxialError', 'Triaxials', 'hartzell4'),
370
- units=_i('Band', 'Bearing', 'Bearing_', 'Bool',
370
+ units=_i('Azimuth', 'Band', 'Bearing', 'Bearing_', 'Bool',
371
371
  'Degrees', 'Degrees_', 'Degrees2', 'Distance', 'Distance_', 'Easting', 'Epoch',
372
372
  'Feet', 'FIx', 'Float_', 'Height', 'Height_', 'HeightX', 'Int_',
373
373
  'Lam', 'Lamd', 'Lat', 'Lat_', 'Lon', 'Lon_',
@@ -521,7 +521,7 @@ class _ALL_MODS(_internals._MODS_Base):
521
521
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
522
522
 
523
523
  __all__ = _ALL_LAZY.lazily
524
- __version__ = '24.07.09'
524
+ __version__ = '24.08.01'
525
525
 
526
526
 
527
527
  def _ALL_OTHER(*objs):
@@ -861,13 +861,13 @@ def _lazy_module(name): # overwritten by _lazy_import2
861
861
  #
862
862
  # return _ALL_OTHER(*sm.values())
863
863
 
864
-
865
864
  # del _i, _i0
866
865
 
867
866
  # _ = _ALL_MODS.errors # force import pygeodesy.errors
868
867
 
869
868
  if _dunder_ismain(__name__): # PYCHOK no cover
870
869
 
870
+ from pygeodesy.internals import _versions
871
871
  from timeit import timeit
872
872
 
873
873
  def t1():
@@ -881,22 +881,24 @@ if _dunder_ismain(__name__): # PYCHOK no cover
881
881
 
882
882
  t1 = timeit(t1, number=1000000)
883
883
  t2 = timeit(t2, number=1000000)
884
- v = _SPACE_.join(_Pythonarchine() + _osversion2())
885
- printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, v)
884
+ printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, _versions())
886
885
 
887
886
  # del t1, t2, timeit, v
888
887
 
889
- # python3.12 -W ignore -m pygeodesy.lazily
890
- # 0.145177 import vs 0.075402 _ALL_MODS: 1.93X, Python 3.12.3 64bit arm64 macOS 14.4.1
888
+ # % python3.13 -W ignore -m pygeodesy.lazily
889
+ # 0.102670 import vs 0.076113 _ALL_MODS: 1.35X, pygeodesy 24.8.4 Python 3.13.0b4 64bit arm64 macOS 14.5
890
+
891
+ # % python3.12 -W ignore -m pygeodesy.lazily
892
+ # 0.132801 import vs 0.079125 _ALL_MODS: 1.68X, pygeodesy 24.8.4 Python 3.12.4 64bit arm64 macOS 14.5
891
893
 
892
- # python3.11 -W ignore -m pygeodesy.lazily
893
- # 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, Python 3.11.5 64bit arm64 macOS 14.4.1
894
+ # % python3.11 -W ignore -m pygeodesy.lazily
895
+ # 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, pygeodesy 24.8.4 Python 3.11.5 64bit arm64 macOS 14.4.1
894
896
 
895
- # python3.10 -W ignore -m pygeodesy.lazily
896
- # 0.378293 import vs 0.266507 _ALL_MODS: 1.42X, Python 3.10.8 64bit arm64 macOS 14.4.1
897
+ # % python3.8 -W ignore -m pygeodesy.lazily
898
+ # 0.570353 import vs 0.382842 _ALL_MODS: 1.49X, pygeodesy 24.8.4 Python 3.8.10 64bit arm64_x86_64 macOS 10.16
897
899
 
898
- # python2 -m pygeodesy.lazily
899
- # 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, Python 2.7.18 64bit arm64_x86_64 macOS 10.16
900
+ # % python2 -m pygeodesy.lazily
901
+ # 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, pygeodesy 24.8.4 Python 2.7.18 64bit arm64_x86_64 macOS 10.16
900
902
 
901
903
  # **) MIT License
902
904
  #
pygeodesy/ltp.py CHANGED
@@ -33,8 +33,8 @@ from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
33
33
  ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
34
34
  from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
35
35
  from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
36
- from pygeodesy.props import Property, Property_RO, property_doc_, property_RO, \
37
- _update_all
36
+ from pygeodesy.props import Property, Property_RO, property_doc_, \
37
+ property_ROver, _update_all
38
38
  from pygeodesy.streprs import Fmt, strs, unstr
39
39
  from pygeodesy.units import Bearing, Degrees, _isHeight, Meter
40
40
  from pygeodesy.utily import cotd, _loneg, sincos2d, sincos2d_, tand, tand_, \
@@ -44,7 +44,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
44
44
  # from math import fabs, floor as _floor # from .fmath, .fsums
45
45
 
46
46
  __all__ = _ALL_LAZY.ltp
47
- __version__ = '24.06.11'
47
+ __version__ = '24.07.25'
48
48
 
49
49
  _height0_ = _height_ + _0_
50
50
  _narrow_ = 'narrow'
@@ -722,15 +722,15 @@ class _ChLV(object):
722
722
  t = Y_X_h_lat_lon_h + (self, self._t0, None) # PYCHOK _t0
723
723
  return ChLV9Tuple(t, name=name)
724
724
 
725
- @property_RO
725
+ @property_ROver
726
726
  def _enh_n_h(self):
727
727
  '''(INTERNAL) Get C{ChLV*.reverse} args[1:4] names, I{once}.
728
728
  '''
729
- _ChLV._enh_n_h = t = _args_kwds_names(_ChLV.reverse)[1:4] # overwrite property_RO
729
+ t = _args_kwds_names(_ChLV.reverse)[1:4]
730
730
  # assert _args_kwds_names( ChLV.reverse)[1:4] == t
731
731
  # assert _args_kwds_names(ChLVa.reverse)[1:4] == t
732
732
  # assert _args_kwds_names(ChLVe.reverse)[1:4] == t
733
- return t
733
+ return t # overwrite property_ROver
734
734
 
735
735
  def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
736
736
  '''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
pygeodesy/ltpTuples.py CHANGED
@@ -28,15 +28,15 @@ from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
28
28
  from pygeodesy.props import deprecated_method, deprecated_Property_RO, \
29
29
  Property_RO, property_RO
30
30
  from pygeodesy.streprs import Fmt, fstr, strs, _xzipairs
31
- from pygeodesy.units import Bearing, Degrees, Degrees_, Height, _isDegrees, \
32
- _isMeter, Lat, Lon, Meter, Meter_
31
+ from pygeodesy.units import Azimuth, Bearing, Degrees, Degrees_, Height, \
32
+ _isDegrees, _isMeter, Lat, Lon, Meter, Meter_
33
33
  from pygeodesy.utily import atan2d, atan2b, sincos2_, sincos2d_, cos, radians
34
34
  from pygeodesy.vector3d import Vector3d
35
35
 
36
36
  # from math import cos, radians # from .utily
37
37
 
38
38
  __all__ = _ALL_LAZY.ltpTuples
39
- __version__ = '24.06.28'
39
+ __version__ = '24.07.25'
40
40
 
41
41
  _aer_ = 'aer'
42
42
  _alt_ = 'alt'
@@ -93,7 +93,7 @@ def _xyz2aer4(inst):
93
93
  '''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
94
94
  '''
95
95
  x, y, z, _ = inst.xyz4
96
- A = Bearing(azimuth=atan2b(x, y))
96
+ A = Azimuth(atan2b(x, y))
97
97
  E = Degrees(elevation=atan2d(z, hypot(x, y)))
98
98
  R = Meter(slantrange=hypot_(x, y, z))
99
99
  return Aer4Tuple(A, E, R, inst.ltp, name=inst.name)
@@ -268,7 +268,7 @@ class Aer(_AbcBase):
268
268
  '''
269
269
  if _isDegrees(azimuth_aer):
270
270
  aer = None
271
- t = (Bearing(azimuth=azimuth_aer),
271
+ t = (Azimuth(azimuth_aer),
272
272
  Degrees_(elevation=elevation, low=_N_90_0, high=_90_0),
273
273
  Meter_(slantrange=slantrange), ltp)
274
274
  else: # PYCHOK no cover
@@ -421,7 +421,7 @@ class Attitude4Tuple(_NamedTuple):
421
421
  the attitude of a plane or camera.
422
422
  '''
423
423
  _Names_ = (_alt_, _tilt_, _yaw_, _roll_)
424
- _Units_ = ( Meter, Bearing, Degrees, Degrees)
424
+ _Units_ = ( Meter, Degrees, Bearing, Degrees)
425
425
 
426
426
  @Property_RO
427
427
  def atyr(self):
pygeodesy/named.py CHANGED
@@ -34,7 +34,7 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
34
34
  # from pygeodesy.units import _toUnit # _MODS
35
35
 
36
36
  __all__ = _ALL_LAZY.named
37
- __version__ = '24.06.24'
37
+ __version__ = '24.07.12'
38
38
 
39
39
  _COMMANL_ = _COMMA_ + _NL_
40
40
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
@@ -1231,9 +1231,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1231
1231
  @return: The B{C{class}}'s C{[module.]class} name (C{str}).
1232
1232
  '''
1233
1233
  try:
1234
- n = clas.__name__
1234
+ n = clas.__name__
1235
1235
  except AttributeError:
1236
- n = _dunder_name_
1236
+ n = clas if isstr(clas) else _dunder_name_
1237
1237
  if prefixed or (classnaming() if prefixed is None else False):
1238
1238
  try:
1239
1239
  m = clas.__module__.rsplit(_DOT_, 1)
pygeodesy/nvectorBase.py CHANGED
@@ -29,7 +29,7 @@ from pygeodesy.named import _xother3, _under
29
29
  from pygeodesy.namedTuples import Trilaterate5Tuple, Vector3Tuple, \
30
30
  Vector4Tuple, map1
31
31
  from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
32
- property_RO, _update_all
32
+ property_RO, property_ROnce, _update_all
33
33
  from pygeodesy.streprs import Fmt, hstr, unstr
34
34
  from pygeodesy.units import Bearing, Height, Radius_, Scalar
35
35
  from pygeodesy.utily import sincos2d, _unrollon, _unrollon3
@@ -38,7 +38,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
38
38
  from math import fabs, sqrt
39
39
 
40
40
  __all__ = _ALL_LAZY.nvectorBase
41
- __version__ = '24.06.12'
41
+ __version__ = '24.07.12'
42
42
 
43
43
 
44
44
  class NvectorBase(Vector3d): # XXX kept private
@@ -78,12 +78,11 @@ class NvectorBase(Vector3d): # XXX kept private
78
78
  '''
79
79
  return self._datum
80
80
 
81
- @property_RO
81
+ @property_ROnce
82
82
  def Ecef(self):
83
83
  '''Get the ECEF I{class} (L{EcefKarney}), I{once}.
84
84
  '''
85
- NvectorBase.Ecef = E = _MODS.ecef.EcefKarney # overwrite property_RO
86
- return E
85
+ return _MODS.ecef.EcefKarney
87
86
 
88
87
  @property_RO
89
88
  def ellipsoidalNvector(self):
pygeodesy/props.py CHANGED
@@ -25,7 +25,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
25
25
  from functools import wraps as _wraps
26
26
 
27
27
  __all__ = _ALL_LAZY.props
28
- __version__ = '24.05.26'
28
+ __version__ = '24.07.23'
29
29
 
30
30
  _class_ = 'class'
31
31
  _dont_use_ = _DEPRECATED_ + ", don't use."
@@ -48,11 +48,12 @@ def _allPropertiesOf(Clas_or_inst, *Bases, **excls):
48
48
  except AttributeError:
49
49
  raise
50
50
  S = () # not an inst
51
- B = Bases or _PropertyBase
52
- _isa = isinstance
51
+ B = Bases or _PropertyBase
52
+ P = _property_RO___
53
53
  for C in S:
54
54
  for n, p in C.__dict__.items():
55
- if _isa(p, B) and p.name == n and n not in excls:
55
+ if isinstance(p, B) and p.name == n and not (
56
+ isinstance(p, P) or n in excls):
56
57
  yield p
57
58
 
58
59
 
@@ -251,9 +252,9 @@ class Property_RO(_PropertyBase):
251
252
  <https://Docs.Python.org/3/library/functools.html#functools.cache>}
252
253
  to I{cache} or I{memoize} the property value.
253
254
 
254
- @see: Luciano Ramalho, "Fluent Python", O'Reilly, Example 19-24, 2016
255
- p. 636 or Example 22-28, 2022 p. 870 and U{class Property
256
- <https://docs.Python.org/3/howto/descriptor.html>}.
255
+ @see: Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 636
256
+ Example 19-24 or 2022 p. 870 Example 22-28 and U{class
257
+ Property<https://docs.Python.org/3/howto/descriptor.html>}.
257
258
  '''
258
259
  _fget = method if _FOR_DOCS else self._fget # XXX force method.__doc__ to epydoc
259
260
  _PropertyBase.__init__(self, method, _fget, self._fset_error)
@@ -355,6 +356,61 @@ class property_RO(_PropertyBase):
355
356
  inst.__dict__.pop(uname)
356
357
 
357
358
 
359
+ class _property_RO___(_PropertyBase):
360
+ # No __doc__ on purpose
361
+
362
+ def __init__(self, method, doc=NN): # PYCHOK expected
363
+ '''New C{property_ROnce} or C{property_ROver}, holding a singleton value as
364
+ class attribute for all instances of that class and overwriting C{self},
365
+ the C{property_ROver} instance in the 1st invokation.
366
+
367
+ @see: L{property_RO} for further details.
368
+ '''
369
+ _PropertyBase.__init__(self, method, self._fget, self._fset_error, doc=doc)
370
+
371
+ def _fdel(self, unused): # PYCHOK no cover
372
+ '''Silently ignored, always.
373
+ '''
374
+ pass
375
+
376
+ def _update(self, *unused): # PYCHOK signature
377
+ '''(INTERNAL) No-op, ignore updates.
378
+ '''
379
+ pass
380
+
381
+
382
+ class property_ROnce(_property_RO___):
383
+ # No __doc__ on purpose
384
+
385
+ def _fget(self, inst):
386
+ '''Get the C{property} value, only I{once} and memoize/cache it.
387
+ '''
388
+ try:
389
+ v = self._val
390
+ except AttributeError:
391
+ v = self._val = self.method(inst)
392
+ return v
393
+
394
+
395
+ class property_ROver(_property_RO___):
396
+ # No __doc__ on purpose
397
+
398
+ def _fget(self, inst):
399
+ '''Get the C{property} value I{once} and overwrite C{self}, this C{property} instance.
400
+ '''
401
+ v = self.method(inst)
402
+ n = self.name
403
+ C = inst.__class__
404
+ for c in C.__mro__: # [:-1]
405
+ if getattr(c, n, None) is self:
406
+ setattr(c, n, v) # overwrite property_ROver
407
+ break
408
+ else:
409
+ n = _DOT_(C.__name__, n)
410
+ raise _AssertionError(_EQUALSPACED_(n, v))
411
+ return v
412
+
413
+
358
414
  class _NamedProperty(property):
359
415
  '''Class C{property} with retrievable name.
360
416
  '''
@@ -372,16 +428,18 @@ def property_doc_(doc):
372
428
 
373
429
  @example:
374
430
 
375
- >>> @property_doc_("documentation text.")
376
- >>> def name(self):
377
- >>> ...
431
+ >>>class Clas(object):
432
+ >>>
433
+ >>> @property_doc_("documentation text.")
434
+ >>> def name(self):
435
+ >>> ...
378
436
  >>>
379
- >>> @name.setter
380
- >>> def name(self, value):
381
- >>> ...
437
+ >>> @name.setter
438
+ >>> def name(self, value):
439
+ >>> ...
382
440
  '''
383
- # See Luciano Ramalho, "Fluent Python", O'Reilly, Example 7-23,
384
- # 2016 p. 212+, 2022 p. 331+, Example 9-22 and <https://
441
+ # See Luciano Ramalho, "Fluent Python", O'Reilly, 2016 p. 212+
442
+ # Example 7-23 or 2022 p. 331+ Example 9-22 and <https://
385
443
  # Python-3-Patterns-Idioms-Test.ReadTheDocs.io/en/latest/PythonDecorators.html>
386
444
 
387
445
  def _documented_property(method):
@@ -396,8 +454,8 @@ def property_doc_(doc):
396
454
  def _deprecated(call, kind, qual_d):
397
455
  '''(INTERNAL) Decorator for DEPRECATED functions, methods, etc.
398
456
 
399
- @see: Brett Slatkin, "Effective Python", page 105, 2nd ed,
400
- Addison-Wesley, 2019.
457
+ @see: Brett Slatkin, "Effective Python", 2019 page 105, 2nd
458
+ ed, Addison-Wesley.
401
459
  '''
402
460
  doc = _docof(call)
403
461
 
pygeodesy/rhumb/solve.py CHANGED
@@ -21,7 +21,7 @@ from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
21
21
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
22
22
 
23
23
  __all__ = _ALL_LAZY.rhumb_solve
24
- __version__ = '24.06.28'
24
+ __version__ = '24.07.11'
25
25
 
26
26
 
27
27
  class _RhumbSolveBase(_SolveGDictBase):
@@ -173,7 +173,7 @@ class RhumbSolve(_RhumbSolveBase):
173
173
  return r
174
174
 
175
175
  def _GDictInverse(self, lat1, lon1, lat2, lon2, *unused, **floats): # PYCHOK signature
176
- '''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but I{without} C{_S_CALPs_}.
176
+ '''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but I{without} C{_SALP_CALPs_}.
177
177
  '''
178
178
  i = _RhumbSolveBase._GDictInverse(self, lat1, lon1, lat2, lon2, **floats)
179
179
  a = _over(float(i.s12), self._mpd) # for .Inverse1
pygeodesy/solveBase.py CHANGED
@@ -11,8 +11,9 @@ from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
11
11
  from pygeodesy.errors import _AssertionError, _xkwds_get, _xkwds_get1, \
12
12
  _xkwds_item2
13
13
  from pygeodesy.internals import _enquote, printf
14
- from pygeodesy.interns import NN, _0_, _BACKSLASH_, _COMMASPACE_, \
15
- _EQUAL_, _Error_, _SPACE_, _UNUSED_
14
+ from pygeodesy.interns import NN, _0_, _AT_,_BACKSLASH_, _COLONSPACE_, \
15
+ _COMMASPACE_, _EQUAL_, _Error_, _SPACE_, \
16
+ _UNUSED_
16
17
  from pygeodesy.karney import Caps, _CapsBase, GDict
17
18
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _sys_version_info2
18
19
  from pygeodesy.named import callername, _name2__, notOverloaded
@@ -24,7 +25,7 @@ from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
24
25
  from subprocess import PIPE as _PIPE, Popen as _Popen, STDOUT as _STDOUT
25
26
 
26
27
  __all__ = _ALL_LAZY.solveBase
27
- __version__ = '24.07.08'
28
+ __version__ = '24.07.11'
28
29
 
29
30
  _ERROR_ = 'ERROR'
30
31
  _Popen_kwds = dict(creationflags=0,
@@ -54,7 +55,7 @@ def _cmd_stdin_(cmd, stdin): # PYCHOK no cover
54
55
 
55
56
  def _popen2(cmd, stdin=None): # in .mgrs, test.bases, .testMgrs
56
57
  '''(INTERNAL) Invoke C{B{cmd} tuple} and return C{exitcode}
57
- and all output from C{stdout/-err}.
58
+ and all output from C{stdout/-err}, I{stripped}.
58
59
  '''
59
60
  p = _Popen(cmd, **_Popen_kwds) # PYCHOK kwArgs
60
61
  r = p.communicate(stdin)[0] # stdout + NL + stderr
@@ -67,6 +68,7 @@ class _SolveCapsBase(_CapsBase):
67
68
  _datum = _WGS84
68
69
  _Error = None
69
70
  _Exact = True
71
+ _invokat = _AT_
70
72
  _invokation = 0
71
73
  _linelimit = 0
72
74
  _prec = Precision_(prec=DIG)
@@ -100,7 +102,7 @@ class _SolveCapsBase(_CapsBase):
100
102
  v = map(float, v) # _float_int, see Intersectool._XDistInvoke
101
103
  return Dict(_zip(n, v)) # strict=True
102
104
 
103
- def _DictInvoke2(self, cmd, Names, Dict, args, **floats_R):
105
+ def _DictInvoke2(self, cmd, args, Names, Dict, **floats_R):
104
106
  '''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
105
107
  '''
106
108
  N = len(Names)
@@ -172,6 +174,16 @@ class _SolveCapsBase(_CapsBase):
172
174
 
173
175
  f = flattening
174
176
 
177
+ def invokat(self, *prefix):
178
+ '''Get and set the invokation number C{"@"} prefix (C{str}).
179
+
180
+ @return: Previous prefix (C{str}).
181
+ '''
182
+ p = self._invokat
183
+ if prefix:
184
+ set._invokat = str(prefix[0])
185
+ return p
186
+
175
187
  @property_RO
176
188
  def invokation(self):
177
189
  '''Get the most recent C{Solve} invokation number (C{int}).
@@ -223,7 +235,7 @@ class _SolveCapsBase(_CapsBase):
223
235
  raise self._Error(cmd=t or _cmd_stdin_(cmd, stdin), cause=x)
224
236
  self._status = s
225
237
  if self.verbose: # and _R is None: # PYCHOK no cover
226
- self._print(repr(r))
238
+ self._print(repr(r), 'stdout/-err')
227
239
  return r
228
240
 
229
241
  def linelimit(self, *limit):
@@ -268,14 +280,16 @@ class _SolveCapsBase(_CapsBase):
268
280
  _update_all(self)
269
281
  self._prec = prec
270
282
 
271
- def _print(self, line): # PYCHOK no cover
283
+ def _print(self, line, *suffix): # PYCHOK no cover
272
284
  '''(INTERNAL) Print a status line.
273
285
  '''
274
286
  if self._linelimit:
275
287
  line = clips(line, limit=self._linelimit, length=True)
276
288
  if self.status is not None:
277
- line = _SPACE_(line, Fmt.PAREN(self.status))
278
- printf('%s@%d: %s', self.named2, self.invokation, line)
289
+ s = _COMMASPACE_(self.status, *suffix)
290
+ line = _SPACE_(line, Fmt.PAREN(s))
291
+ p = NN(self.named2, self._invokat, self.invokation)
292
+ printf(_COLONSPACE_(p, line))
279
293
 
280
294
  def _setXable(self, path, **Xable_path):
281
295
  '''(INTERNAL) Set the executable C{path}.
@@ -411,7 +425,7 @@ class _SolveGDictBase(_SolveBase):
411
425
  lat, lon, azi, s12_a12, **floats)
412
426
 
413
427
  def _GDictInverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
414
- '''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but I{without} C{_S_CALPs_}.
428
+ '''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but I{without} C{_SALP_CALPs_}.
415
429
  '''
416
430
  return self._GDictInvoke(self._cmdInverse, self._Names_Inverse,
417
431
  lat1, lon1, lat2, lon2, **floats)
@@ -419,7 +433,7 @@ class _SolveGDictBase(_SolveBase):
419
433
  def _GDictInvoke(self, cmd, Names, *args, **floats):
420
434
  '''(INTERNAL) Invoke C{Solve}, return results as C{Dict}.
421
435
  '''
422
- return self._DictInvoke2(cmd, Names, GDict, args, **floats)[0] # _R
436
+ return self._DictInvoke2(cmd, args, Names, GDict, **floats)[0] # _R
423
437
 
424
438
  def Inverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_): # PYCHOK unused
425
439
  '''Return the C{Inverse} result.
@@ -456,7 +470,7 @@ class _SolveGDictLineBase(_SolveGDictBase):
456
470
  if name:
457
471
  self.name = name
458
472
 
459
- self._caps = caps | Caps._LINE
473
+ self._caps = caps | Caps._AZIMUTH_LATITUDE_LONG_UNROLL
460
474
  self._debug = solve._debug & Caps._DEBUG_ALL
461
475
  self._lla1 = GDict(lat1=lat1, lon1=lon1, **azi)
462
476
  self._solve = solve
pygeodesy/triaxials.py CHANGED
@@ -49,7 +49,7 @@ from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, \
49
49
  _NamedEnumItem, _Pass
50
50
  from pygeodesy.namedTuples import LatLon3Tuple, _NamedTupleTo, Vector3Tuple, \
51
51
  Vector4Tuple
52
- from pygeodesy.props import Property_RO, property_RO
52
+ from pygeodesy.props import Property_RO, property_ROver
53
53
  # from pygeodesy.streprs import Fmt # from .datums
54
54
  from pygeodesy.units import Degrees, Float, Height_, Meter, Meter2, Meter3, \
55
55
  Radians, Radius, Scalar_
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
59
59
  from math import atan2, fabs, sqrt
60
60
 
61
61
  __all__ = _ALL_LAZY.triaxials
62
- __version__ = '24.06.24'
62
+ __version__ = '24.07.29'
63
63
 
64
64
  _not_ordered_ = _not_('ordered')
65
65
  _omega_ = 'omega'
@@ -360,12 +360,11 @@ class Triaxial_(_NamedEnumItem):
360
360
 
361
361
  _1e2bc = _c2_b2 # C{1 - e2bc} == C{(c/b)**2}
362
362
 
363
- @property_RO
363
+ @property_ROver
364
364
  def _Elliptic(self):
365
365
  '''(INTERNAL) Get class L{Elliptic}, I{once}.
366
366
  '''
367
- Triaxial_._Elliptic = E = _MODS.elliptic.Elliptic # overwrite property_RO
368
- return E
367
+ return _MODS.elliptic.Elliptic # overwrite property_ROver
369
368
 
370
369
  def hartzell4(self, pov, los=False, **name):
371
370
  '''Compute the intersection of this triaxial's surface with a Line-Of-Sight
@@ -754,7 +753,7 @@ class Triaxial(Triaxial_):
754
753
  return self.height4(x_xyz, y, z, **normal_eps_name)
755
754
 
756
755
  def forwardLatLon(self, lat, lon, height=0, **name):
757
- '''Convert I{geodetic} lat-, longitude and heigth to cartesian.
756
+ '''Convert I{geodetic} lat-, longitude and height to cartesian.
758
757
 
759
758
  @arg lat: Geodetic latitude (C{degrees}).
760
759
  @arg lon: Geodetic longitude (C{degrees}).
@@ -770,7 +769,7 @@ class Triaxial(Triaxial_):
770
769
  return self._forwardLatLon3(height, name, *sincos2d_(lat, lon))
771
770
 
772
771
  def forwardLatLon_(self, slat, clat, slon, clon, height=0, **name):
773
- '''Convert I{geodetic} lat-, longitude and heigth to cartesian.
772
+ '''Convert I{geodetic} lat-, longitude and height to cartesian.
774
773
 
775
774
  @arg slat: Geodetic latitude C{sin(lat)} (C{scalar}).
776
775
  @arg clat: Geodetic latitude C{cos(lat)} (C{scalar}).