pygeodesy 25.10.10__py2.py3-none-any.whl → 25.11.5__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pygeodesy/__init__.py CHANGED
@@ -605,7 +605,7 @@ else:
605
605
 
606
606
  from pygeodesy.internals import _version2, _DOT_ # noqa: E402
607
607
  # from pygeodesy.interns import _DOT_ # from .internals
608
- __version__ = '25.10.10'
608
+ __version__ = '25.11.05'
609
609
  # see setup.py for similar logic
610
610
  version = _DOT_(*_version2(__version__, n=3))
611
611
 
pygeodesy/booleans.py CHANGED
@@ -45,7 +45,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
45
45
  # from math import fabs # from .utily
46
46
 
47
47
  __all__ = _ALL_LAZY.booleans
48
- __version__ = '25.09.04'
48
+ __version__ = '25.10.30'
49
49
 
50
50
  _0EPS = EPS # near-zero, positive
51
51
  _EPS0 = -EPS # near-zero, negative
@@ -1434,17 +1434,14 @@ class _CompositeGH(_CompositeBase):
1434
1434
 
1435
1435
  def _clip(self, corners, s_entry, c_entry, Clas=None,
1436
1436
  **closed_inull_raiser_xtend_eps):
1437
- # Clip this polygon with another one, C{corners}.
1438
-
1439
- # Core of Greiner/Hormann's algorithm, enhanced U{Correia's
1440
- # <https://GitHub.com/helderco/univ-polyclip>} implementation***
1441
- # and extended to optionally handle so-called "degenerate cases"
1437
+ # Clip this polygon with another one, C{corners}, using
1438
+ # Greiner/Hormann's algorithm extended to optionally
1439
+ # handle some so-called "degenerate cases"
1442
1440
  S = self
1443
1441
  C = self._class(corners, closed_inull_raiser_xtend_eps,
1444
1442
  raiser=False, xtend=False)
1445
1443
  bt = C._bottom_top_eps2
1446
1444
  lr = C._left_right_eps2
1447
-
1448
1445
  # 1. find intersections
1449
1446
  for s1, s2, Sc in S._edges3(**closed_inull_raiser_xtend_eps):
1450
1447
  if not (_outside(s1.x, s2.x, *lr) or
@@ -1507,13 +1504,13 @@ class _CompositeGH(_CompositeBase):
1507
1504
 
1508
1505
  @property
1509
1506
  def xtend(self):
1510
- '''Get the option to handle I{degenerate cases} (C{bool}).
1507
+ '''Get the option to handle some I{degenerate cases} (C{bool}).
1511
1508
  '''
1512
1509
  return self._xtend
1513
1510
 
1514
1511
  @xtend.setter # PYCHOK setter!
1515
1512
  def xtend(self, xtend):
1516
- '''Set the option to handle I{degenerate cases} (C{bool}).
1513
+ '''Set the option to handle some I{degenerate cases} (C{bool}).
1517
1514
  '''
1518
1515
  self._xtend = bool(xtend)
1519
1516
 
@@ -1825,9 +1822,7 @@ class BooleanFHP(_CompositeFHP, _BooleanBase):
1825
1822
  class BooleanGH(_CompositeGH, _BooleanBase):
1826
1823
  '''I{Composite} class providing I{boolean} operations between two
1827
1824
  I{composites} using the U{Greiner-Hormann<http://www.Inf.USI.CH/
1828
- hormann/papers/Greiner.1998.ECO.pdf>} algorithm and U{Correia
1829
- <https://GitHub.com/helderco/univ-polyclip>}'s implementation,
1830
- modified and extended.
1825
+ hormann/papers/Greiner.1998.ECO.pdf>} algorithm, extended.
1831
1826
 
1832
1827
  The supported operations between (composite) polygon A and B are:
1833
1828
 
@@ -2003,23 +1998,3 @@ __all__ += _ALL_DOCS(_BooleanBase, _Clip,
2003
1998
  # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2004
1999
  # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005
2000
  # OTHER DEALINGS IN THE SOFTWARE.
2006
-
2007
- # ***) GNU GPL 3
2008
- #
2009
- # Copyright (C) 2011-2012 Helder Correia <Helder.MC@Gmail.com>
2010
- #
2011
- # This program is free software: you can redistribute it and/or
2012
- # modify it under the terms of the GNU General Public License as
2013
- # published by the Free Software Foundation, either version 3 of
2014
- # the License, or any later version.
2015
- #
2016
- # This program is distributed in the hope that it will be useful,
2017
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
2018
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2019
- # GNU General Public License for more details.
2020
- #
2021
- # You should have received a copy of the GNU General Public License
2022
- # along with this program. If not, see <http://www.GNU.org/licenses/>.
2023
- #
2024
- # You should have received the README file along with this program.
2025
- # If not, see <https://GitHub.com/helderco/univ-polyclip>.
pygeodesy/clipy.py CHANGED
@@ -31,7 +31,7 @@ from pygeodesy.units import Bool, FIx, HeightX, Lat, Lon, Number_
31
31
  # from math import fabs # from .fmath
32
32
 
33
33
  __all__ = _ALL_LAZY.clipy
34
- __version__ = '25.05.12'
34
+ __version__ = '25.10.30'
35
35
 
36
36
  _fj_ = 'fj'
37
37
  _original_ = 'original'
@@ -237,9 +237,8 @@ def clipCS4(points, lowerleft, upperight, closed=False, inull=False):
237
237
 
238
238
 
239
239
  class ClipFHP4Tuple(_NamedTuple):
240
- '''4-Tuple C{(lat, lon, height, clipid)} for each point of the
241
- L{clipFHP4} result with the C{lat}-, C{lon}gitude, C{height}
242
- and C{clipid} of the polygon or clip.
240
+ '''4-Tuple C{(lat, lon, height, clipid)} for each point of the L{clipFHP4} result
241
+ with the C{lat}-, C{lon}gitude, C{height} and C{clipid} of the polygon or clip.
243
242
 
244
243
  @note: The C{height} is a L{HeightX} instance if this point is
245
244
  an intersection, otherwise a L{Height} or C{int(0)}.
@@ -275,14 +274,13 @@ def clipFHP4(points, corners, closed=False, inull=False, raiser=False, eps=EPS):
275
274
  as the B{C{points}} and B{C{corners}} coordinates).
276
275
 
277
276
  @return: Yield a L{ClipFHP4Tuple}C{(lat, lon, height, clipid)} for each
278
- clipped point. The result may consist of several clips, each
279
- a (closed) polygon with a unique C{clipid}.
277
+ clipped point. The result may consist of several I{clips}, each
278
+ a (closed) polygon with a unique C{clipid} identifier.
280
279
 
281
280
  @raise ClipError: Insufficient B{C{points}} or B{C{corners}} or an open clip.
282
281
 
283
282
  @see: U{Forster, Hormann and Popa<https://www.ScienceDirect.com/science/
284
- article/pii/S259014861930007X>}, class L{BooleanFHP} and function
285
- L{clipGH4}.
283
+ article/pii/S259014861930007X>} and class L{BooleanFHP}.
286
284
  '''
287
285
  P = _MODS.booleans._CompositeFHP(points, kind=_points_, raiser=raiser,
288
286
  eps=eps, name__=clipFHP4)
@@ -292,12 +290,11 @@ def clipFHP4(points, corners, closed=False, inull=False, raiser=False, eps=EPS):
292
290
 
293
291
 
294
292
  class ClipGH4Tuple(ClipFHP4Tuple):
295
- '''4-Tuple C{(lat, lon, height, clipid)} for each point of the
296
- L{clipGH4} result with the C{lat}-, C{lon}gitude, C{height}
297
- and C{clipid} of the polygon or clip.
293
+ '''4-Tuple C{(lat, lon, height, clipid)} for each point of the L{clipGH4} result
294
+ with the C{lat}-, C{lon}gitude, C{height} and C{clipid} of the polygon or clip.
298
295
 
299
- @note: The C{height} is a L{HeightX} instance if this is
300
- an intersection, otherwise a L{Height} or C{int(0)}.
296
+ @note: The C{height} is a L{HeightX} instance if this is an intersection,
297
+ otherwise a L{Height} or C{int(0)}.
301
298
  '''
302
299
  _Names_ = ClipFHP4Tuple._Names_
303
300
  _Units_ = ClipFHP4Tuple._Units_
@@ -305,8 +302,7 @@ class ClipGH4Tuple(ClipFHP4Tuple):
305
302
 
306
303
  def clipGH4(points, corners, closed=False, inull=False, raiser=True, xtend=False, eps=EPS):
307
304
  '''Clip one or more polygons against a clip region or box using the U{Greiner-Hormann
308
- <http://www.Inf.USI.CH/hormann/papers/Greiner.1998.ECO.pdf>} algorithm, U{Correia
309
- <https://GitHub.com/helderco/univ-polyclip>}'s implementation modified and extended.
305
+ <http://www.Inf.USI.CH/hormann/papers/Greiner.1998.ECO.pdf>} algorithm, extended.
310
306
 
311
307
  @arg points: The polygon points and clips (C{LatLon}[]).
312
308
  @arg corners: Three or more points defining the clip regions (C{LatLon}[])
@@ -320,19 +316,17 @@ def clipGH4(points, corners, closed=False, inull=False, raiser=True, xtend=False
320
316
  as the B{C{points}} and B{C{corners}} coordinates).
321
317
 
322
318
  @return: Yield a L{ClipGH4Tuple}C{(lat, lon, height, clipid)} for each
323
- clipped point. The result may consist of several clips, each
324
- a (closed) polygon with a unique C{clipid}.
319
+ clipped point. The result may consist of several I{clips}, each
320
+ a (closed) polygon with a unique C{clipid} identifier.
325
321
 
326
322
  @raise ClipError: Insufficient B{C{points}} or B{C{corners}}, an open clip,
327
323
  a I{degenerate case} or I{unhandled} intersection.
328
324
 
329
325
  @note: To handle I{degenerate cases} like C{point-edge} and C{point-point}
330
- intersections, use function L{clipFHP4}.
326
+ intersections I{properly}, use function L{clipFHP4}.
331
327
 
332
- @see: U{Greiner-Hormann<https://WikiPedia.org/wiki/Greiner–Hormann_clipping_algorithm>},
333
- U{Ionel Daniel Stroe<https://Davis.WPI.edu/~matt/courses/clipping/>}, I{Correia}'s
334
- U{univ-polyclip<https://GitHub.com/helderco/univ-polyclip>}, class L{BooleanGH}
335
- and function L{clipFHP4}.
328
+ @see: U{Greiner-Hormann<https://WikiPedia.org/wiki/Greiner–Hormann_clipping_algorithm>}
329
+ and class L{BooleanGH}.
336
330
  '''
337
331
  S = _MODS.booleans._CompositeGH(points, raiser=raiser, xtend=xtend, eps=eps,
338
332
  name__=clipGH4, kind=_points_)
pygeodesy/constants.py CHANGED
@@ -11,7 +11,7 @@ L{pygeodesy.isnon0} and L{pygeodesy.remainder}.
11
11
  from __future__ import division as _; del _ # noqa: E702 ;
12
12
 
13
13
  from pygeodesy.basics import _copysign, isbool, iscomplex, isint, signBit
14
- from pygeodesy.errors import _xError, _xError2, _xkwds_get1, _xkwds_item2
14
+ from pygeodesy.errors import _ValueError, _xError, _xkwds_get1, _xkwds_item2
15
15
  # from pygeodesy.fsums import _isFsum_2Tuple # _MODS
16
16
  from pygeodesy.internals import _0_0, _100_0, typename
17
17
  from pygeodesy.interns import _DMAIN_, _INF_, _NAN_
@@ -26,7 +26,7 @@ except ImportError: # Python 2-
26
26
  _inf, _nan = float(_INF_), float(_NAN_)
27
27
 
28
28
  __all__ = _ALL_LAZY.constants
29
- __version__ = '25.09.11'
29
+ __version__ = '25.10.15'
30
30
 
31
31
 
32
32
  def _copysign_0_0(y):
@@ -47,7 +47,7 @@ def _copysignINF(y):
47
47
  return NINF if signBit(y) else INF
48
48
 
49
49
 
50
- def _flipsign(x, y):
50
+ def _flipsign(x, y=-1):
51
51
  '''(INTERNAL) Negate C{x} for negative C{y}.
52
52
  '''
53
53
  return (-x) if signBit(y) else x
@@ -60,65 +60,78 @@ def _Float(**name_arg):
60
60
  return Float(_float(arg), name=n)
61
61
 
62
62
 
63
- def _Radius(**name_arg):
64
- '''(INTERNAL) New named, cached C{Radius}.
63
+ def _float(x): # in .datums, .ellipsoids, ...
64
+ '''(INTERNAL) Cache initial C{float}s.
65
65
  '''
66
- n, arg = _xkwds_item2(name_arg)
67
- return Radius(_float(arg), name=n)
66
+ f = float(x)
67
+ return _floats.setdefault(f, f) # PYCHOK del _floats
68
68
 
69
69
 
70
- def float_(*fs, **sets): # sets=False
71
- '''Get scalars as C{float} or I{intern}'ed C{float}.
70
+ def float_(x, sets=False):
71
+ '''Get scalar as C{float} or I{intern}'ed C{float}.
72
72
 
73
- @arg fs: One more values (C{scalar}), all positional.
74
- @kwarg sets: Use C{B{sets}=True} to C{intern} each
75
- B{C{fs}}, otherwise don't C{intern}.
73
+ @arg x: The scalar (C{scalar}).
74
+ @kwarg sets: Use C{True} to C{intern} the B{C{f}},
75
+ otherwise don't (C{bool}).
76
76
 
77
- @return: A single C{float} if only one B{C{fs}} is
78
- given, otherwise a tuple of C{float}s.
77
+ @return: A C{float}.
79
78
 
80
- @raise TypeError: Some B{C{fs}} is not C{scalar}.
79
+ @raise ValueError: Invalid B{C{x}}.
81
80
  '''
82
- fl = []
83
- _a = fl.append
84
- _f = _floats.setdefault if _xkwds_get1(sets, sets=False) else \
85
- _floats.get
86
81
  try:
87
- for i, f in enumerate(fs):
88
- f = float(f)
89
- _a(_f(f, f))
90
- except Exception as x:
91
- E, t = _xError2(x)
92
- fs_i = Fmt.SQUARE(fs=i)
93
- raise E(fs_i, f, txt=t)
94
- return fl[0] if len(fl) == 1 else tuple(fl)
95
-
96
-
97
- def _float(f): # in .datums, .ellipsoids, ...
98
- '''(INTERNAL) Cache initial C{float}s.
99
- '''
100
- f = float(f)
101
- return _floats.setdefault(f, f) # PYCHOK del _floats
82
+ f = float(x)
83
+ if f:
84
+ _f = _floats.setdefault if sets else _floats.get
85
+ f = _f(f, f)
86
+ else:
87
+ f = _N_0_0 if signBit(f) else _0_0
88
+ except Exception as X:
89
+ raise _ValueError(x=x, cause=X)
90
+ return f
102
91
 
103
92
 
104
93
  def float0_(*xs):
105
94
  '''Yield C{B{x}s} as a non-NEG0 C{float}.
106
95
  '''
107
96
  for x in xs:
108
- yield float(x) if x else _0_0
97
+ yield float(x) or _0_0 # if x else _0_0
109
98
 
110
99
 
111
- def _float0(f): # in .auxilats.auxily, .resections, .vector3dBase, ...
100
+ def _float0(x): # in .auxilats.auxily, .resections, .vector3dBase, ...
112
101
  '''(INTERNAL) Return C{float(B{f})} or C{INT0}.
113
102
  '''
114
- if f:
115
- f = float(f)
103
+ if x:
104
+ f = float(x)
116
105
  f = _floats.get(f, f)
117
- elif f is not INT0:
118
- f = float(f) or _0_0 # force None, NN error
106
+ elif x is INT0:
107
+ f = x
108
+ else:
109
+ f = float(x) or _0_0 # force None, NN error
119
110
  return f
120
111
 
121
112
 
113
+ def floats_(*xs, **sets): # sets=False
114
+ '''Yield each scalar as C{float} or I{intern}'ed C{float}.
115
+
116
+ @arg xs: One more values (C{scalar}), all positional.
117
+ @kwarg sets: Use C{B{sets}=True} to C{intern} each
118
+ B{C{fs}}, otherwise don't C{intern}.
119
+
120
+ @raise ValueError: Some B{C{xs}} is not C{scalar}.
121
+ '''
122
+ if sets:
123
+ sets = _xkwds_get1(sets, sets=False)
124
+ _f = _floats.setdefault if sets else _floats.get
125
+ try:
126
+ for i, x in enumerate(xs):
127
+ f = float(x)
128
+ yield _f(f, f) if f else \
129
+ (_N_0_0 if signBit(f) else _0_0) # preserve NEG0
130
+ except Exception as X:
131
+ xs_i = Fmt.SQUARE(xs=i)
132
+ raise _ValueError(xs_i, x, cause=X)
133
+
134
+
122
135
  def _floatuple(*fs):
123
136
  '''(INTERNAL) Cache a tuple of C{float}s.
124
137
  '''
@@ -172,6 +185,13 @@ def _1_over(x):
172
185
  return NINF if isneg0(x) else INF
173
186
 
174
187
 
188
+ def _Radius(**name_arg):
189
+ '''(INTERNAL) New named, cached C{Radius}.
190
+ '''
191
+ n, arg = _xkwds_item2(name_arg)
192
+ return Radius(_float(arg), name=n)
193
+
194
+
175
195
  _floats = {} # PYCHOK floats cache, in .__main__
176
196
  # _float = float # PYCHOK expected
177
197
  # del _floats # XXX zap floats cache never
@@ -27,7 +27,7 @@ __all__ = (_ALL_DEPRECATED.deprecated_bases +
27
27
  _ALL_DEPRECATED.deprecated_classes +
28
28
  _ALL_DEPRECATED.deprecated_consterns +
29
29
  _ALL_DEPRECATED.deprecated_functions)
30
- __version__ = '25.05.12'
30
+ __version__ = '25.10.25'
31
31
 
32
32
  if _unLazy0:
33
33
  from pygeodesy.deprecated import bases, datum, nvector, rhumbBase, \
@@ -18,11 +18,12 @@ from pygeodesy.namedTuples import Forward4Tuple as _Forward4Tuple, \
18
18
  UtmUps5Tuple as _UtmUps5Tuple, _NamedTuple
19
19
  from pygeodesy.props import deprecated_class, deprecated_method
20
20
  from pygeodesy.resections import TriAngle5Tuple as _TriAngle5Tuple
21
+ from pygeodesy.triaxials import ConformalSphere, ConformalTriaxial, Conformal2Tuple
21
22
  from pygeodesy.trf import TRFXform7Tuple as _TRFXform7Tuple
22
23
  from pygeodesy.units import Bearing, Int, Lamd, Lat, Lon, Meter, Phid
23
24
 
24
25
  __all__ = _ALL_DEPRECATED.deprecated_classes
25
- __version__ = '25.04.11'
26
+ __version__ = '25.10.25'
26
27
 
27
28
 
28
29
  class _Deprecated_NamedTuple(_NamedTuple):
@@ -235,6 +236,28 @@ def HeightIDWcosineForsytheAndoyerLambert(knots, **kwds): # PYCHOK no cover
235
236
  return HeightIDWcosineForsytheAndoyerLambert(knots, **kwds)
236
237
 
237
238
 
239
+ class JacobiConformal(ConformalTriaxial):
240
+ '''DEPRECATED on 2025.10.25, use class L{ConformalTriaxial}.'''
241
+ def __init__(self, *args, **kwds): # PYCHOK no cover
242
+ deprecated_class(self.__class__)
243
+ ConformalTriaxial.__init__(self, *args, **kwds)
244
+
245
+
246
+ class JacobiConformalSpherical(ConformalSphere):
247
+ '''DEPRECATED on 2025.10.25, use class L{ConformalSphere}.'''
248
+ def __init__(self, *args, **kwds): # PYCHOK no cover
249
+ deprecated_class(self.__class__)
250
+ ConformalSphere.__init__(self, *args, **kwds)
251
+
252
+
253
+ class Jacobi2Tuple(Conformal2Tuple):
254
+ '''DEPRECATED on 25.10.25, use class L{Conformal2Tuple}.
255
+ '''
256
+ def __new__(cls, *args, **kwds):
257
+ deprecated_class(cls)
258
+ return Conformal2Tuple.__new__(cls, *args, **kwds)
259
+
260
+
238
261
  class Lam_(Lamd):
239
262
  '''DEPRECATED on 2024.06.15, use class L{Lamd}.'''
240
263
  def __init__(self, *args, **kwds): # PYCHOK no cover
pygeodesy/errors.py CHANGED
@@ -28,7 +28,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYTHON_X_DEV
28
28
  from copy import copy as _copy
29
29
 
30
30
  __all__ = _ALL_LAZY.errors # _ALL_DOCS('_InvalidError', '_IsnotError') _under
31
- __version__ = '25.09.04'
31
+ __version__ = '25.10.30'
32
32
 
33
33
  _argument_ = 'argument'
34
34
  _basics = _MODS.into(basics=__name__)
pygeodesy/internals.py CHANGED
@@ -498,7 +498,7 @@ def printf(fmt, *args, **nl_nt_prec_prefix__end_file_flush_sep__kwds):
498
498
  t = fmt
499
499
  except Exception as x:
500
500
  _Error, s = _MODS.errors._xError2(x)
501
- _unstr = _MODS.strepr.unstr
501
+ _unstr = _MODS.streprs.unstr
502
502
  t = _unstr(printf, fmt, *args, **nl_nt_prec_prefix__end_file_flush_sep__kwds)
503
503
  raise _Error(s, txt=t, cause=x)
504
504
  try:
@@ -709,7 +709,7 @@ def _versions(sep=_SPACE_):
709
709
 
710
710
 
711
711
  __all__ = tuple(map(typename, (machine, print_, printf, typename)))
712
- __version__ = '25.10.06'
712
+ __version__ = '25.10.26'
713
713
 
714
714
  if __name__ == _DMAIN_:
715
715
 
pygeodesy/lazily.py CHANGED
@@ -203,7 +203,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
203
203
  'INF', 'INT0', 'MANT_DIG', 'MAX', 'MAX_EXP', 'MIN', 'MIN_EXP', 'NAN', 'NEG0', 'NINF',
204
204
  'PI', 'PI2', 'PI_2', 'PI3', 'PI_3', 'PI3_2', 'PI4', 'PI_4', 'PI_6',
205
205
  'R_FM', 'R_GM', 'R_KM', 'R_M', 'R_MA', 'R_MB', 'R_NM', 'R_QM', 'R_SM', 'R_VM',
206
- 'float_', 'float0_', 'isclose', 'isfinite', 'isinf', 'isint0',
206
+ 'float_', 'float0_', 'floats_', 'isclose', 'isfinite', 'isinf', 'isint0',
207
207
  'isnan', 'isnear0', 'isnear1', 'isnear90', 'isneg', 'isneg0', 'isninf', 'isnon0',
208
208
  'remainder'),
209
209
  datums=_a('Datum', 'Datums', 'Transform', 'Transforms'),
@@ -346,9 +346,9 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
346
346
  'lrstrip', 'pairs', 'reprs', 'strs', 'unstr'),
347
347
  trf=_a('RefFrame', 'RefFrames', 'TransformXform', 'TRFXform', 'TRFXform7Tuple',
348
348
  'date2epoch', 'epoch2date', 'trfTransform0', 'trfTransforms', 'trfXform'),
349
- triaxials=_a('BetaOmega2Tuple', 'BetaOmega3Tuple', 'Jacobi2Tuple',
350
- 'JacobiConformal', 'JacobiConformalSpherical',
351
- 'Triaxial', 'Triaxial_', 'TriaxialError', 'Triaxials', 'hartzell4'),
349
+ triaxials=_a('BetaOmega2Tuple', 'BetaOmega3Tuple',
350
+ 'ConformalSphere', 'ConformalTriaxial', 'Conformal2Tuple',
351
+ 'Triaxial', 'Triaxial_', 'TriaxialError', 'Triaxials', 'hartzell4'), # 'height4'
352
352
  units=_a('Azimuth', 'Band', 'Bearing', 'Bearing_', 'Bool',
353
353
  'Degrees', 'Degrees_', 'Degrees2', 'Distance', 'Distance_', 'Easting', 'Epoch',
354
354
  'Feet', 'FIx', 'Float_', 'Height', 'Height_', 'HeightX', 'Int_',
@@ -394,6 +394,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
394
394
  'HausdorffCosineAndoyerLambert', 'HausdorffCosineForsytheAndoyerLambert',
395
395
  'HeightIDW', 'HeightIDW2', 'HeightIDW3', 'HeightIDWcosineAndoyerLambert',
396
396
  'HeightIDWcosineForsytheAndoyerLambert', 'Helmert7Tuple',
397
+ 'JacobiConformal', 'JacobiConformalSpherical', 'Jacobi2Tuple',
397
398
  'Lam_', 'LatLonExact4Tuple', 'NearestOn4Tuple', 'Ned3Tuple',
398
399
  'Phi_', 'RefFrameError', 'Rhumb7Tuple', 'RhumbOrder2Tuple',
399
400
  'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple', 'XDist'),
@@ -511,7 +512,7 @@ class _ALL_MODS(_internals._MODS_Base):
511
512
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
512
513
 
513
514
  __all__ = _ALL_LAZY.lazily
514
- __version__ = '25.09.09'
515
+ __version__ = '25.10.30'
515
516
 
516
517
 
517
518
  def _ALL_OTHER(*objs):