pygeodesy 25.11.5__py2.py3-none-any.whl → 25.12.31__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 (125) hide show
  1. pygeodesy/__init__.py +46 -25
  2. pygeodesy/__main__.py +1 -1
  3. pygeodesy/albers.py +1 -1
  4. pygeodesy/angles.py +960 -0
  5. pygeodesy/auxilats/_CX_4.py +1 -1
  6. pygeodesy/auxilats/_CX_6.py +1 -1
  7. pygeodesy/auxilats/_CX_8.py +1 -1
  8. pygeodesy/auxilats/_CX_Rs.py +1 -1
  9. pygeodesy/auxilats/__init__.py +2 -2
  10. pygeodesy/auxilats/__main__.py +1 -1
  11. pygeodesy/auxilats/auxAngle.py +7 -8
  12. pygeodesy/auxilats/auxDLat.py +1 -1
  13. pygeodesy/auxilats/auxDST.py +1 -1
  14. pygeodesy/auxilats/auxLat.py +1 -1
  15. pygeodesy/auxilats/auxily.py +1 -1
  16. pygeodesy/azimuthal.py +6 -5
  17. pygeodesy/basics.py +14 -10
  18. pygeodesy/booleans.py +1 -1
  19. pygeodesy/cartesianBase.py +7 -7
  20. pygeodesy/clipy.py +1 -1
  21. pygeodesy/constants.py +29 -24
  22. pygeodesy/css.py +1 -1
  23. pygeodesy/datums.py +1 -1
  24. pygeodesy/deprecated/__init__.py +1 -1
  25. pygeodesy/deprecated/bases.py +1 -1
  26. pygeodesy/deprecated/classes.py +14 -7
  27. pygeodesy/deprecated/consterns.py +1 -1
  28. pygeodesy/deprecated/datum.py +1 -1
  29. pygeodesy/deprecated/functions.py +1 -1
  30. pygeodesy/deprecated/nvector.py +1 -1
  31. pygeodesy/deprecated/rhumbBase.py +1 -1
  32. pygeodesy/deprecated/rhumbaux.py +1 -1
  33. pygeodesy/deprecated/rhumbsolve.py +1 -1
  34. pygeodesy/deprecated/rhumbx.py +1 -1
  35. pygeodesy/dms.py +1 -1
  36. pygeodesy/ecef.py +1 -1
  37. pygeodesy/ecefLocals.py +1 -1
  38. pygeodesy/elevations.py +1 -1
  39. pygeodesy/ellipsoidalBase.py +1 -1
  40. pygeodesy/ellipsoidalBaseDI.py +1 -1
  41. pygeodesy/ellipsoidalExact.py +1 -1
  42. pygeodesy/ellipsoidalGeodSolve.py +1 -1
  43. pygeodesy/ellipsoidalKarney.py +1 -1
  44. pygeodesy/ellipsoidalNvector.py +1 -1
  45. pygeodesy/ellipsoidalVincenty.py +1 -1
  46. pygeodesy/ellipsoids.py +30 -17
  47. pygeodesy/elliptic.py +1 -1
  48. pygeodesy/epsg.py +1 -1
  49. pygeodesy/errors.py +8 -4
  50. pygeodesy/etm.py +1 -1
  51. pygeodesy/fmath.py +19 -14
  52. pygeodesy/formy.py +251 -10
  53. pygeodesy/frechet.py +1 -1
  54. pygeodesy/fstats.py +1 -1
  55. pygeodesy/fsums.py +41 -29
  56. pygeodesy/gars.py +1 -1
  57. pygeodesy/geod3solve.py +489 -0
  58. pygeodesy/geodesici.py +9 -8
  59. pygeodesy/geodesicw.py +1 -1
  60. pygeodesy/geodesicx/_C4_24.py +1 -1
  61. pygeodesy/geodesicx/_C4_27.py +1 -1
  62. pygeodesy/geodesicx/_C4_30.py +1 -1
  63. pygeodesy/geodesicx/__init__.py +2 -2
  64. pygeodesy/geodesicx/__main__.py +1 -1
  65. pygeodesy/geodesicx/gx.py +1 -1
  66. pygeodesy/geodesicx/gxarea.py +54 -24
  67. pygeodesy/geodesicx/gxbases.py +1 -1
  68. pygeodesy/geodesicx/gxline.py +1 -1
  69. pygeodesy/geodsolve.py +73 -104
  70. pygeodesy/geohash.py +1 -1
  71. pygeodesy/geoids.py +1 -1
  72. pygeodesy/hausdorff.py +1 -1
  73. pygeodesy/heights.py +1 -1
  74. pygeodesy/internals.py +1 -1
  75. pygeodesy/interns.py +3 -3
  76. pygeodesy/iters.py +1 -1
  77. pygeodesy/karney.py +152 -151
  78. pygeodesy/ktm.py +1 -1
  79. pygeodesy/latlonBase.py +1 -1
  80. pygeodesy/lazily.py +24 -13
  81. pygeodesy/lcc.py +1 -1
  82. pygeodesy/ltp.py +1 -1
  83. pygeodesy/ltpTuples.py +1 -1
  84. pygeodesy/mgrs.py +3 -3
  85. pygeodesy/named.py +15 -10
  86. pygeodesy/namedTuples.py +1 -1
  87. pygeodesy/nvectorBase.py +1 -1
  88. pygeodesy/osgr.py +1 -1
  89. pygeodesy/points.py +1 -1
  90. pygeodesy/props.py +6 -4
  91. pygeodesy/resections.py +1 -1
  92. pygeodesy/rhumb/__init__.py +8 -6
  93. pygeodesy/rhumb/aux_.py +1 -1
  94. pygeodesy/rhumb/bases.py +1 -1
  95. pygeodesy/rhumb/ekx.py +1 -1
  96. pygeodesy/rhumb/solve.py +91 -84
  97. pygeodesy/simplify.py +1 -1
  98. pygeodesy/solveBase.py +72 -49
  99. pygeodesy/sphericalBase.py +1 -1
  100. pygeodesy/sphericalNvector.py +1 -1
  101. pygeodesy/sphericalTrigonometry.py +1 -1
  102. pygeodesy/streprs.py +6 -4
  103. pygeodesy/trf.py +2 -4
  104. pygeodesy/triaxials/__init__.py +70 -0
  105. pygeodesy/triaxials/bases.py +966 -0
  106. pygeodesy/triaxials/conformal3.py +617 -0
  107. pygeodesy/triaxials/triaxial3.py +968 -0
  108. pygeodesy/{triaxials.py → triaxials/triaxial5.py} +353 -781
  109. pygeodesy/units.py +1 -1
  110. pygeodesy/unitsBase.py +1 -1
  111. pygeodesy/ups.py +2 -3
  112. pygeodesy/utily.py +17 -14
  113. pygeodesy/utm.py +1 -1
  114. pygeodesy/utmups.py +1 -1
  115. pygeodesy/utmupsBase.py +1 -1
  116. pygeodesy/vector2d.py +1 -1
  117. pygeodesy/vector3d.py +1 -1
  118. pygeodesy/vector3dBase.py +1 -1
  119. pygeodesy/webmercator.py +1 -1
  120. pygeodesy/wgrs.py +1 -1
  121. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.31.dist-info}/METADATA +28 -21
  122. pygeodesy-25.12.31.dist-info/RECORD +125 -0
  123. pygeodesy-25.11.5.dist-info/RECORD +0 -119
  124. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.31.dist-info}/WHEEL +0 -0
  125. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.31.dist-info}/top_level.txt +0 -0
@@ -19,19 +19,20 @@ from __future__ import division as _; del _ # noqa: E702 ;
19
19
 
20
20
  from pygeodesy.basics import _copysign, isodd, unsigned0
21
21
  from pygeodesy.constants import NAN, _0_0, _0_5, _720_0
22
+ from pygeodesy.fmath import _fma
22
23
  from pygeodesy.internals import printf, typename
23
24
  # from pygeodesy.interns import _COMMASPACE_ # from .lazily
24
25
  from pygeodesy.karney import Area3Tuple, _diff182, GeodesicError, \
25
- _norm180, _remainder, _sum3
26
+ _norm180, _remainder, _sum2
26
27
  from pygeodesy.lazily import _ALL_DOCS, _COMMASPACE_
27
28
  from pygeodesy.named import ADict, callername, _NamedBase, pairs
28
29
  from pygeodesy.props import Property, Property_RO, property_RO
29
30
  # from pygeodesy.streprs import pairs # from .named
30
31
 
31
- from math import fmod as _fmod
32
+ from math import fabs, fmod as _fmod
32
33
 
33
34
  __all__ = ()
34
- __version__ = '25.09.16'
35
+ __version__ = '25.12.23'
35
36
 
36
37
 
37
38
  class GeodesicAreaExact(_NamedBase):
@@ -427,30 +428,39 @@ class _Accumulator(_NamedBase):
427
428
  @kwarg y: Initial value (C{scalar}).
428
429
  @kwarg name: Optional C{B{name}=NN} (C{str}).
429
430
  '''
430
- if isinstance(y, _Accumulator):
431
- self._s, self._t, self._n = y._s, y._t, 1
432
- elif y:
433
- self._s, self._n = float(y), 1
431
+ self._s_t(*_s_t2(y))
432
+ self._n = 1
434
433
  if name:
435
434
  self.name = name
436
435
 
437
- def Add(self, y):
438
- '''Add a value.
436
+ def Add(self, *ys):
437
+ '''Add one or more scalars or L{_Accumulator}s.
439
438
 
440
439
  @return: Current C{sum}.
441
- '''
442
- self._n += 1
443
- self._s, self._t, _ = _sum3(self._s, self._t, y)
444
- return self._s # current .Sum()
440
+
441
+ @see: C++ U{Accumulator.Add<https://GeographicLib.sourceforge.io/C++/doc/Accumulator_8hpp_source.html>}
442
+ for more details about Karney's and Shewchuk's addition.
443
+ '''
444
+ # _Accumulator().Add(1, 1e20, 2, 100, 5000, -1e20) ... 5103.0
445
+ s, t = self._s, self._t
446
+ for y in ys:
447
+ for y in _s_t2(y):
448
+ if y:
449
+ t, u = _sum2(t, y)
450
+ s, t = _sum2(s, t)
451
+ if s: # accumlate u in t
452
+ t += u
453
+ else: # s == 0 implies t == 0
454
+ s = u
455
+ self._n += 1
456
+ return self._s_t(s, t)
445
457
 
446
458
  def Negate(self):
447
459
  '''Negate sum.
448
460
 
449
461
  @return: Current C{sum}.
450
462
  '''
451
- self._s = s = -self._s
452
- self._t = -self._t
453
- return s # current .Sum()
463
+ return self._s_t(-self._s, -self._t)
454
464
 
455
465
  @property_RO
456
466
  def num(self):
@@ -459,22 +469,27 @@ class _Accumulator(_NamedBase):
459
469
  return self._n
460
470
 
461
471
  def Remainder(self, y):
462
- '''Remainder on division by B{C{y}}.
472
+ '''Remainder of division by B{C{y}}.
463
473
 
464
474
  @return: Remainder of C{sum} / B{C{y}}.
465
475
  '''
466
- self._s = _remainder(self._s, y)
467
- # self._t = _remainder(self._t, y)
468
- self._n = -1
469
- return self.Add(_0_0)
476
+ return self._s_t(_remainder(self._s, y),
477
+ _remainder(self._t, y))
470
478
 
471
479
  def Reset(self, y=0):
472
- '''Set value from argument.
480
+ '''Reset from scalar or L{_Accumulator}.
473
481
  '''
474
- self._n, self._s, self._t = 0, float(y), _0_0
482
+ self._s_t(*_s_t2(y))
483
+ self._n = 0
475
484
 
476
485
  Set = Reset
477
486
 
487
+ def _s_t(self, s, t=0):
488
+ if t and fabs(s) < fabs(t):
489
+ s, t = t, s
490
+ self._s, self._t = s, t
491
+ return s
492
+
478
493
  def Sum(self, y=0):
479
494
  '''Return C{sum + B{y}}.
480
495
 
@@ -488,6 +503,17 @@ class _Accumulator(_NamedBase):
488
503
  s = self
489
504
  return s._s
490
505
 
506
+ def Times(self, y):
507
+ '''Multiply by a scalar.
508
+
509
+ @return: Current C{sum}.
510
+ '''
511
+ s = d = self._s
512
+ s *= y
513
+ d = _fma(y, d, -s)
514
+ t = _fma(y, self._t, d)
515
+ return self._s_t(s, t) # current .Sum()
516
+
491
517
  def toStr(self, prec=6, sep=_COMMASPACE_, **unused): # PYCHOK signature
492
518
  '''Return this C{_Accumulator} as string.
493
519
 
@@ -502,11 +528,15 @@ class _Accumulator(_NamedBase):
502
528
  return sep.join(pairs(d, prec=prec))
503
529
 
504
530
 
531
+ def _s_t2(y):
532
+ return (y._s, y._t) if isinstance(y, _Accumulator) else (float(y),) # PYCHOK OK
533
+
534
+
505
535
  __all__ += _ALL_DOCS(GeodesicAreaExact, PolygonArea)
506
536
 
507
537
  # **) MIT License
508
538
  #
509
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
539
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
510
540
  #
511
541
  # Permission is hereby granted, free of charge, to any person obtaining a
512
542
  # copy of this software and associated documentation files (the "Software"),
@@ -165,7 +165,7 @@ def _xnC4(**name_nC4):
165
165
 
166
166
  # **) MIT License
167
167
  #
168
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
168
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
169
169
  #
170
170
  # Permission is hereby granted, free of charge, to any person obtaining a
171
171
  # copy of this software and associated documentation files (the "Software"),
@@ -667,7 +667,7 @@ __all__ += _ALL_DOCS(_GeodesicLineExact)
667
667
 
668
668
  # **) MIT License
669
669
  #
670
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
670
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
671
671
  #
672
672
  # Permission is hereby granted, free of charge, to any person obtaining a
673
673
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/geodsolve.py CHANGED
@@ -3,33 +3,53 @@
3
3
 
4
4
  u'''Wrapper to invoke I{Karney}'s U{GeodSolve
5
5
  <https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>} utility
6
- as an (exact) geodesic, but intended I{for testing purposes only}.
6
+ as an (exact) geodesic, but intended I{mainly for testing purposes}.
7
7
 
8
- Set env variable C{PYGEODESY_GEODSOLVE} to the (fully qualified) path
9
- of the C{GeodSolve} executable.
8
+ Set env variable C{PYGEODESY_GEODSOLVE} to the (fully qualified) path of
9
+ the C{GeodSolve} executable or use property L{GeodesicSolve.GeodSolve
10
+ <geodsolve._GeodesicSolveBase.GeodSolve>}.
10
11
  '''
11
12
 
12
13
  from pygeodesy.basics import _xinstanceof # typename
13
- # from pygeodesy.constants import NAN, _0_0 # from .karney
14
+ from pygeodesy.constants import NAN, _0_0
15
+ # from pygeodesy.errors import GeodesicError # from .karney
14
16
  # from pygeodesy.geodesicx import GeodesicAreaExact # _MODS
15
- from pygeodesy.interns import _DMAIN_, NN, _UNDER_
16
- from pygeodesy.karney import Caps, GeodesicError, GeodSolve12Tuple, \
17
- _sincos2d, _Xables, _0_0, NAN
17
+ from pygeodesy.interns import _a12_, _azi1_, _azi2_, _DMAIN_, _lat1_, \
18
+ _lat2_, _lon1_, _lon2_, _m12_, _M12_, \
19
+ _M21_, NN, _s12_, _S12_, _UNDER_
20
+ from pygeodesy.karney import Caps, _GTuple, _sincos2d, _Xables, _Azi, \
21
+ _Deg, GeodesicError, _Lat, _Lon, _M, _M2
18
22
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
19
- from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
23
+ from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple, \
24
+ _Pass
20
25
  from pygeodesy.props import Property, Property_RO, property_RO
21
26
  from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
27
+ # from pygeodesy.units import Azimuth as _Azi, Degrees as _Deg, \
28
+ # Meter as _M, Meter2 as _M2 # from .karney
22
29
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
23
30
 
24
31
  __all__ = _ALL_LAZY.geodsolve
25
- __version__ = '25.09.03'
32
+ __version__ = '25.12.31'
33
+
34
+
35
+ class GeodSolve12Tuple(_GTuple):
36
+ '''12-Tuple C{(lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12)} with
37
+ angles C{lat1}, C{lon1}, C{azi1}, C{lat2}, C{lon2} and C{azi2} and arc C{a12} all in
38
+ C{degrees}, initial C{azi1} and final C{azi2} forward azimuths in bearings, degrees
39
+ from North, distance C{s12} and reduced length C{m12} in C{meter}, area C{S12} in
40
+ C{meter} I{squared} and geodesic scale factors C{M12} and C{M21}, both C{scalar}, see
41
+ U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}.
42
+ '''
43
+ # from GeodSolve --help option -f ... lat1 lon1 azi1 lat2 lon2 azi2 s12 a12 m12 M12 M21 S12
44
+ _Names_ = (_lat1_, _lon1_, _azi1_, _lat2_, _lon2_, _azi2_, _s12_, _a12_, _m12_, _M12_, _M21_, _S12_)
45
+ _Units_ = (_Lat, _Lon, _Azi, _Lat, _Lon, _Azi, _M, _Deg, _Pass, _Pass, _Pass, _M2)
26
46
 
27
47
 
28
48
  class _GeodesicSolveBase(_SolveGDictBase):
29
49
  '''(INTERNAL) Base class for L{GeodesicSolve} and L{GeodesicLineSolve}.
30
50
  '''
31
51
  _Error = GeodesicError
32
- _Names_Direct = \
52
+ _Names_Direct = _Names_Distance = \
33
53
  _Names_Inverse = GeodSolve12Tuple._Names_
34
54
  _Xable_name = _Xables.GeodSolve.__name__ # typename
35
55
  _Xable_path = _Xables.GeodSolve()
@@ -65,19 +85,6 @@ class _GeodesicSolveBase(_SolveGDictBase):
65
85
  '''
66
86
  self._setXable(path)
67
87
 
68
- def toStr(self, **prec_sep): # PYCHOK signature
69
- '''Return this C{GeodesicSolve} as string.
70
-
71
- @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
72
- for the C{float} C{prec}ision, number of decimal digits
73
- (0..9) and the C{sep}arator string to join. Trailing
74
- zero decimals are stripped for B{C{prec}} values of 1
75
- and above, but kept for negative B{C{prec}} values.
76
-
77
- @return: GeodesicSolve items (C{str}).
78
- '''
79
- return _SolveGDictBase._toStr(self, GeodSolve=self.GeodSolve, **prec_sep)
80
-
81
88
  @Property_RO
82
89
  def _u_option(self):
83
90
  return ('-u',) if self.unroll else ()
@@ -203,6 +210,15 @@ class GeodesicSolve(_GeodesicSolveBase):
203
210
  gl._s13 = r.s12 # gl.SetDistance(r.s12)
204
211
  return gl
205
212
 
213
+ def toStr(self, **prec_sep_other): # PYCHOK signature
214
+ '''Return this C{GeodesicSolve} as string.
215
+
216
+ @kwarg prec_sep: See L{toStr<pygeodesy.solveBase._SolveBase.toStr>}.
217
+
218
+ @return: GeodesicSolve items (C{str}).
219
+ '''
220
+ return _SolveGDictBase.toStr(self, GeodSolve=self.GeodSolve, **prec_sep_other)
221
+
206
222
 
207
223
  class GeodesicLineSolve(_GeodesicSolveBase, _SolveGDictLineBase):
208
224
  '''Wrapper to invoke I{Karney}'s U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}
@@ -271,7 +287,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveGDictLineBase):
271
287
  @return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
272
288
  azi2, m12, a12, s12, M12, M21, S12}.
273
289
  '''
274
- return self._GDictInvoke(self._cmdArc, self._Names_Direct, a12)._unCaps(outmask)
290
+ return self._GDictInvoke(self._cmdArc, self._Names_Distance, a12)._unCaps(outmask)
275
291
 
276
292
  @Property_RO
277
293
  def azi1(self):
@@ -315,14 +331,14 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveGDictLineBase):
315
331
  self._notImplemented(lat0, lon0, **kwds)
316
332
 
317
333
  def Position(self, s12, outmask=Caps.STANDARD):
318
- '''Find the position on the line given B{C{s12}}.
334
+ '''Find the position on the line given at distance B{C{s12}}.
319
335
 
320
336
  @arg s12: Distance from the first point to the second (C{meter}).
321
337
 
322
338
  @return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
323
339
  azi2, m12, a12, s12, M12, M21, S12}, possibly C{a12=NAN}.
324
340
  '''
325
- return self._GDictInvoke(self._cmdDistance, self._Names_Direct, s12)._unCaps(outmask)
341
+ return self._GDictInvoke(self._cmdDistance, self._Names_Distance, s12)._unCaps(outmask)
326
342
 
327
343
  @Property_RO
328
344
  def s13(self):
@@ -361,19 +377,14 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveGDictLineBase):
361
377
  # _update_all(self)
362
378
  return self._a13 # NAN for GeodesicLineExact without Cap.DISTANCE_IN
363
379
 
364
- def toStr(self, **prec_sep): # PYCHOK signature
380
+ def toStr(self, **prec_sep_other): # PYCHOK signature
365
381
  '''Return this C{GeodesicLineSolve} as string.
366
382
 
367
- @kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
368
- for the C{float} C{prec}ision, number of decimal digits
369
- (0..9) and the C{sep}arator string to join. Trailing
370
- zero decimals are stripped for B{C{prec}} values of 1
371
- and above, but kept for negative B{C{prec}} values.
383
+ @kwarg prec_sep: See L{toStr<pygeodesy.solveBase._SolveBase.toStr>}.
372
384
 
373
385
  @return: GeodesicLineSolve items (C{str}).
374
386
  '''
375
- return _SolveGDictLineBase._toStr(self, azi1=self.azi1, geodesic=self._solve,
376
- GeodSolve=self.GeodSolve, **prec_sep)
387
+ return _SolveGDictLineBase.toStr(self, geodesic=self._solve, **prec_sep_other)
377
388
 
378
389
 
379
390
  __all__ += _ALL_DOCS(_GeodesicSolveBase)
@@ -385,120 +396,78 @@ if __name__ == _DMAIN_:
385
396
  from sys import argv
386
397
 
387
398
  gS = GeodesicSolve(name='Test')
388
- gS.verbose = '--verbose' in argv # or '-v' in argv
399
+ gS.verbose = v = '--verbose' in argv # or '-v' in argv
389
400
 
390
401
  if not _Xables.X_OK(gS.GeodSolve): # not set
391
402
  gS.GeodSolve = _Xables.GeodSolve(_Xables.bin_)
392
- printf('version: %s', gS.version)
403
+ printf('version: %s', gS.version, nt=v)
393
404
 
394
405
  r = gS.Direct(40.6, -73.8, 51, 5.5e6)
395
- printf('Direct: %r', r, nl=1)
396
- printf('Direct3: %r', gS.Direct3(40.6, -73.8, 51, 5.5e6))
406
+ printf('Direct: %r', r)
407
+ printf('Direct3: %r', gS.Direct3(40.6, -73.8, 51, 5.5e6), nt=v)
397
408
 
398
- printf('Inverse: %r', gS.Inverse( 40.6, -73.8, 51.6, -0.5), nl=1)
409
+ printf('Inverse: %r', gS.Inverse( 40.6, -73.8, 51.6, -0.5))
399
410
  printf('Inverse1: %r', gS.Inverse1(40.6, -73.8, 51.6, -0.5))
400
- printf('Inverse3: %r', gS.Inverse3(40.6, -73.8, 51.6, -0.5))
411
+ printf('Inverse3: %r', gS.Inverse3(40.6, -73.8, 51.6, -0.5), nt=v)
401
412
 
402
413
  glS = GeodesicLineSolve(gS, 40.6, -73.8, 51, name='LineTest')
414
+ printf('Line: %r', glS)
403
415
  p = glS.Position(5.5e6)
404
- printf('Position: %5s %r', p == r, p, nl=1)
416
+ printf('Position: %r %s', p, p == r)
405
417
  p = glS.ArcPosition(49.475527)
406
- printf('ArcPosition: %5s %r', p == r, p)
418
+ printf('ArcPosition: %r %s', p, p == r)
407
419
 
408
420
  _main()
409
421
 
410
422
  # % python3 -m pygeodesy.geodsolve
411
423
 
412
- # version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
413
-
414
- # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
415
- # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
416
-
417
- # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
418
- # Inverse1: 49.94131021789904
419
- # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
420
-
421
- # Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
422
- # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
423
-
424
-
425
- # % python3 -m pygeodesy.geodsolve
426
-
427
- # version: /opt/local/bin/GeodSolve: GeographicLib version 2.3
428
-
424
+ # version: /opt/local/bin/GeodSolve: GeographicLib version 2.7
429
425
  # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.078125)
430
426
  # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
431
-
432
427
  # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
433
428
  # Inverse1: 49.94131021789904
434
429
  # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
435
-
436
- # Position: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, s12=5500000.0)
437
- # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, s12=5499999.948497)
438
-
439
-
440
- # % python3 -m pygeodesy.geodsolve --verbose
441
-
442
- # GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve --version (invoke)
443
- # GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve: GeographicLib version 2.2 (0)
444
- # version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
445
- # GeodesicSolve 'Test' 2: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
446
- # GeodesicSolve 'Test' 2: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
447
-
448
- # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
449
- # GeodesicSolve 'Test' 3: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
450
- # GeodesicSolve 'Test' 3: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
451
- # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
452
- # GeodesicSolve 'Test' 4: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
453
- # GeodesicSolve 'Test' 4: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
454
-
455
- # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
456
- # GeodesicSolve 'Test' 5: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
457
- # GeodesicSolve 'Test' 5: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
458
- # Inverse1: 49.94131021789904
459
- # GeodesicSolve 'Test' 6: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
460
- # GeodesicSolve 'Test' 6: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
461
- # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
462
-
463
- # Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
464
- # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
430
+ # Line: GeodesicLineSolve(geodesic=GeodesicSolve(ellipsoid=Ellipsoid(name='WGS84', a=6378137, f=0.00335281, f_=298.25722356, b=6356752.31424518), GeodSolve='/opt/local/bin/GeodSolve', invokation=6, status=0), invokation=1, status=0)
431
+ # Position: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, s12=5500000.0) False
432
+ # ArcPosition: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, s12=5499999.948497) False
465
433
 
466
434
 
467
435
  # % python3 -m pygeodesy.geodsolve --verbose
468
436
 
469
437
  # GeodesicSolve 'Test'@1: /opt/local/bin/GeodSolve --version (invoke)
470
- # GeodesicSolve 'Test'@1: '/opt/local/bin/GeodSolve: GeographicLib version 2.3' (0, stdout/-err)
471
- # GeodesicSolve 'Test'@1: /opt/local/bin/GeodSolve: GeographicLib version 2.3 (0)
472
- # version: /opt/local/bin/GeodSolve: GeographicLib version 2.3
473
- # GeodesicSolve 'Test'@2: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
438
+ # GeodesicSolve 'Test'@1: '/opt/local/bin/GeodSolve: GeographicLib version 2.7' (0, stdout/-err)
439
+ # GeodesicSolve 'Test'@1: /opt/local/bin/GeodSolve: GeographicLib version 2.7 (0)
440
+ # version: /opt/local/bin/GeodSolve: GeographicLib version 2.7
441
+ #
442
+ # GeodesicSolve 'Test'@2: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.6 -73.8 51.0 5500000.0 (Direct)
474
443
  # GeodesicSolve 'Test'@2: '40.600000000000001 -73.799999999999997 51.000000000000000 51.884564505606761 -1.141172861200843 107.189397162605871 5500000.0000000000 49.475527463251460 4844148.7031014860 0.65091056699808614 0.65122865892196569 39735075134877.078' (0, stdout/-err)
475
444
  # GeodesicSolve 'Test'@2: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200843, azi2=107.189397162605871, s12=5500000.0, a12=49.47552746325146, m12=4844148.703101486, M12=0.65091056699808614, M21=0.65122865892196569, S12=39735075134877.078 (0)
476
-
477
445
  # Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.078125)
478
- # GeodesicSolve 'Test'@3: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
446
+ # GeodesicSolve 'Test'@3: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.6 -73.8 51.0 5500000.0 (Direct3)
479
447
  # GeodesicSolve 'Test'@3: '40.600000000000001 -73.799999999999997 51.000000000000000 51.884564505606761 -1.141172861200843 107.189397162605871 5500000.0000000000 49.475527463251460 4844148.7031014860 0.65091056699808614 0.65122865892196569 39735075134877.078' (0, stdout/-err)
480
448
  # GeodesicSolve 'Test'@3: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200843, azi2=107.189397162605871, s12=5500000.0, a12=49.47552746325146, m12=4844148.703101486, M12=0.65091056699808614, M21=0.65122865892196569, S12=39735075134877.078 (0)
481
449
  # Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
482
- # GeodesicSolve 'Test'@4: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
450
+ #
451
+ # GeodesicSolve 'Test'@4: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.6 -73.8 51.6 -0.5 (Inverse)
483
452
  # GeodesicSolve 'Test'@4: '40.600000000000001 -73.799999999999997 51.198882845579824 51.600000000000001 -0.500000000000000 107.821776735514248 5551759.4003186813 49.941310217899037 4877684.6027061967 0.64472969205948238 0.64504567852134398 40041368848742.531' (0, stdout/-err)
484
453
  # GeodesicSolve 'Test'@4: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186813, a12=49.941310217899037, m12=4877684.6027061967, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
485
-
486
454
  # Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
487
- # GeodesicSolve 'Test'@5: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
455
+ # GeodesicSolve 'Test'@5: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.6 -73.8 51.6 -0.5 (Inverse1)
488
456
  # GeodesicSolve 'Test'@5: '40.600000000000001 -73.799999999999997 51.198882845579824 51.600000000000001 -0.500000000000000 107.821776735514248 5551759.4003186813 49.941310217899037 4877684.6027061967 0.64472969205948238 0.64504567852134398 40041368848742.531' (0, stdout/-err)
489
457
  # GeodesicSolve 'Test'@5: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186813, a12=49.941310217899037, m12=4877684.6027061967, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
490
458
  # Inverse1: 49.94131021789904
491
- # GeodesicSolve 'Test'@6: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
459
+ # GeodesicSolve 'Test'@6: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.6 -73.8 51.6 -0.5 (Inverse3)
492
460
  # GeodesicSolve 'Test'@6: '40.600000000000001 -73.799999999999997 51.198882845579824 51.600000000000001 -0.500000000000000 107.821776735514248 5551759.4003186813 49.941310217899037 4877684.6027061967 0.64472969205948238 0.64504567852134398 40041368848742.531' (0, stdout/-err)
493
461
  # GeodesicSolve 'Test'@6: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186813, a12=49.941310217899037, m12=4877684.6027061967, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
494
462
  # Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
495
-
496
- # Position: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, s12=5500000.0)
497
- # ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, s12=5499999.948497)
463
+ #
464
+ # Line: GeodesicLineSolve(geodesic=GeodesicSolve(ellipsoid=Ellipsoid(name='WGS84', a=6378137, f=0.00335281, f_=298.25722356, b=6356752.31424518), GeodSolve='/opt/local/bin/GeodSolve', invokation=6, status=0), invokation=1, status=0)
465
+ # Position: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, s12=5500000.0) False
466
+ # ArcPosition: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, s12=5499999.948497) False
498
467
 
499
468
  # **) MIT License
500
469
  #
501
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
470
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
502
471
  #
503
472
  # Permission is hereby granted, free of charge, to any person obtaining a
504
473
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/geohash.py CHANGED
@@ -1098,7 +1098,7 @@ if __name__ == _DMAIN_:
1098
1098
 
1099
1099
  # **) MIT License
1100
1100
  #
1101
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1101
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1102
1102
  #
1103
1103
  # Permission is hereby granted, free of charge, to any person obtaining a
1104
1104
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/geoids.py CHANGED
@@ -1912,7 +1912,7 @@ del _intCs, _T, _T0s12 # trash ints cache and map
1912
1912
 
1913
1913
  # **) MIT License
1914
1914
  #
1915
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1915
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1916
1916
  #
1917
1917
  # Permission is hereby granted, free of charge, to any person obtaining a
1918
1918
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/hausdorff.py CHANGED
@@ -828,7 +828,7 @@ def randomrangenerator(seed):
828
828
 
829
829
  # **) MIT License
830
830
  #
831
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
831
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
832
832
  #
833
833
  # Permission is hereby granted, free of charge, to any person obtaining a
834
834
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/heights.py CHANGED
@@ -1073,7 +1073,7 @@ __all__ += _ALL_DOCS(_HeightBase, _HeightIDW, _HeightNamed)
1073
1073
 
1074
1074
  # **) MIT License
1075
1075
  #
1076
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1076
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1077
1077
  #
1078
1078
  # Permission is hereby granted, free of charge, to any person obtaining a
1079
1079
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/internals.py CHANGED
@@ -726,7 +726,7 @@ if __name__ == _DMAIN_:
726
726
 
727
727
  # **) MIT License
728
728
  #
729
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
729
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
730
730
  #
731
731
  # Permission is hereby granted, free of charge, to any person obtaining a
732
732
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/interns.py CHANGED
@@ -10,7 +10,7 @@ except NameError: # Python 3+
10
10
  _intern = _sys.intern
11
11
 
12
12
  _COMMASPACE_ = ', ' # overriden below
13
- _SUB_PACKAGES = 'auxilats', 'deprecated', 'geodesicx', 'rhumb' # PYCHOK in ...
13
+ _SUB_PACKAGES = 'auxilats', 'deprecated', 'geodesicx', 'rhumb', 'triaxials' # PYCHOK in ...
14
14
  # ... .lazily, make._dist, MANIFEST, setup.setup, test/bases, test/testModules
15
15
 
16
16
 
@@ -443,7 +443,7 @@ _LR_PAIRS = {_LANGLE_: _RANGLE_,
443
443
 
444
444
  __all__ = (_NN_, # NOT MISSING!
445
445
  Str_.__name__) # classes
446
- __version__ = '25.05.26'
446
+ __version__ = '25.11.07'
447
447
 
448
448
  if __name__ == _DMAIN_:
449
449
 
@@ -466,7 +466,7 @@ if __name__ == _DMAIN_:
466
466
 
467
467
  # **) MIT License
468
468
  #
469
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
469
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
470
470
  #
471
471
  # Permission is hereby granted, free of charge, to any person obtaining a
472
472
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/iters.py CHANGED
@@ -527,7 +527,7 @@ __all__ += _ALL_DOCS(_BaseIter)
527
527
 
528
528
  # **) MIT License
529
529
  #
530
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
530
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
531
531
  #
532
532
  # Permission is hereby granted, free of charge, to any person obtaining a
533
533
  # copy of this software and associated documentation files (the "Software"),