pygeodesy 25.7.25__py2.py3-none-any.whl → 25.9.9__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. pygeodesy/__init__.py +10 -9
  2. pygeodesy/auxilats/__init__.py +1 -1
  3. pygeodesy/auxilats/auxAngle.py +4 -3
  4. pygeodesy/auxilats/auxily.py +1 -1
  5. pygeodesy/basics.py +4 -4
  6. pygeodesy/booleans.py +25 -25
  7. pygeodesy/cartesianBase.py +21 -20
  8. pygeodesy/constants.py +37 -7
  9. pygeodesy/deprecated/functions.py +1 -0
  10. pygeodesy/dms.py +2 -2
  11. pygeodesy/ecef.py +324 -260
  12. pygeodesy/ellipsoidalExact.py +4 -4
  13. pygeodesy/ellipsoidalGeodSolve.py +3 -3
  14. pygeodesy/ellipsoids.py +79 -52
  15. pygeodesy/elliptic.py +8 -11
  16. pygeodesy/errors.py +18 -5
  17. pygeodesy/etm.py +8 -8
  18. pygeodesy/fmath.py +1 -1
  19. pygeodesy/geodesicx/__init__.py +1 -1
  20. pygeodesy/geodesicx/__main__.py +1 -0
  21. pygeodesy/geodesicx/gx.py +30 -37
  22. pygeodesy/geodesicx/gxbases.py +1 -5
  23. pygeodesy/geodesicx/gxline.py +43 -34
  24. pygeodesy/geodsolve.py +10 -17
  25. pygeodesy/internals.py +39 -15
  26. pygeodesy/karney.py +19 -18
  27. pygeodesy/ktm.py +3 -3
  28. pygeodesy/latlonBase.py +4 -4
  29. pygeodesy/lazily.py +14 -13
  30. pygeodesy/lcc.py +5 -5
  31. pygeodesy/named.py +10 -13
  32. pygeodesy/nvectorBase.py +4 -4
  33. pygeodesy/rhumb/__init__.py +1 -1
  34. pygeodesy/rhumb/aux_.py +1 -1
  35. pygeodesy/rhumb/bases.py +7 -8
  36. pygeodesy/rhumb/ekx.py +9 -9
  37. pygeodesy/solveBase.py +14 -3
  38. pygeodesy/sphericalTrigonometry.py +8 -8
  39. pygeodesy/utily.py +200 -159
  40. pygeodesy/vector3dBase.py +10 -8
  41. {pygeodesy-25.7.25.dist-info → pygeodesy-25.9.9.dist-info}/METADATA +12 -11
  42. {pygeodesy-25.7.25.dist-info → pygeodesy-25.9.9.dist-info}/RECORD +44 -44
  43. {pygeodesy-25.7.25.dist-info → pygeodesy-25.9.9.dist-info}/WHEEL +0 -0
  44. {pygeodesy-25.7.25.dist-info → pygeodesy-25.9.9.dist-info}/top_level.txt +0 -0
pygeodesy/ktm.py CHANGED
@@ -62,11 +62,11 @@ from pygeodesy.props import property_doc_, Property, Property_RO, \
62
62
  from pygeodesy.units import Degrees, Scalar_, _1mm as _TOL_10 # PYCHOK used!
63
63
  from pygeodesy.utily import atan1d, atan2, _loneg, sincos2, sincos2d_
64
64
 
65
- from cmath import polar
65
+ from cmath import polar as _polar
66
66
  from math import asinh, cos, cosh, degrees, fabs, sin, sinh, sqrt, tanh
67
67
 
68
68
  __all__ = _ALL_LAZY.ktm
69
- __version__ = '25.05.12'
69
+ __version__ = '25.08.31'
70
70
 
71
71
 
72
72
  class KTMError(_ValueError):
@@ -476,7 +476,7 @@ def _Cyxgk4(E, xi_, eta_, C):
476
476
 
477
477
  # Gauss-Schreiber to Gauss-Krueger TM
478
478
  # C{cmath.polar} handles INF, NAN, etc.
479
- k, g = polar(c)
479
+ k, g = _polar(c)
480
480
  g = degrees(g)
481
481
  else: # E.isSpherical
482
482
  g, k = _0_0, _1_0
pygeodesy/latlonBase.py CHANGED
@@ -33,7 +33,7 @@ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
33
33
  from pygeodesy.named import _name2__, _NamedBase, Fmt
34
34
  from pygeodesy.namedTuples import Bounds2Tuple, LatLon2Tuple, PhiLam2Tuple, \
35
35
  Trilaterate5Tuple, Vector3Tuple
36
- # from pygeodesy.nvectorBase import _N_vector_ # _MODS
36
+ # from pygeodesy.nvectorBase import _N_Vector # _MODS
37
37
  from pygeodesy.props import deprecated_method, Property, Property_RO, \
38
38
  property_RO, _update_all
39
39
  # from pygeodesy.streprs import Fmt, hstr # from .named, _MODS
@@ -48,7 +48,7 @@ from contextlib import contextmanager
48
48
  from math import asin, cos, degrees, fabs, radians
49
49
 
50
50
  __all__ = _ALL_LAZY.latlonBase
51
- __version__ = '25.05.07'
51
+ __version__ = '25.08.18'
52
52
 
53
53
  _formy = _MODS.into(formy=__name__)
54
54
 
@@ -971,9 +971,9 @@ class LatLonBase(_NamedBase, _EcefLocal):
971
971
 
972
972
  @property_RO
973
973
  def _N_vector(self):
974
- '''(INTERNAL) Get the C{Nvector} (C{nvectorBase._N_vector_})
974
+ '''(INTERNAL) Get the C{Nvector} (C{nvectorBase._N_Vector})
975
975
  '''
976
- _N = _MODS.nvectorBase._N_vector_
976
+ _N = _MODS.nvectorBase._N_Vector
977
977
  return _N(*self._n_xyz3, h=self.height, name=self.name)
978
978
 
979
979
  @Property_RO
pygeodesy/lazily.py CHANGED
@@ -29,15 +29,15 @@ 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, _xkwds_item2 # _ALL_MODS
32
+ # from pygeodesy.errors import _error_init, _ImmutableError, _xkwds_item2 # _ALL_MODS
33
33
  from pygeodesy.internals import _caller3, _envPYGEODESY, _headof, printf, _tailof, \
34
34
  typename, _versions # _getenv, _PYGEODESY_ENV, \
35
35
  # _MODS_Base, _MODS.sys_version_info2
36
36
  from pygeodesy.interns import _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, _DALL_, \
37
37
  _DMAIN_, _doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
38
- _HASH_, _immutable_, _line_, _module_, NN, _no_, _not_, \
39
- _pygeodesy_, _pygeodesy_abspath_, _SPACE_, _SUB_PACKAGES, \
40
- _or_, _UNDER_, _version_, _sys, _intern # function, _1_
38
+ _HASH_, _line_, _module_, NN, _no_, _not_, _pygeodesy_, \
39
+ _pygeodesy_abspath_, _SPACE_, _SUB_PACKAGES, _or_, \
40
+ _UNDER_, _version_, _sys, _intern # function, _1_
41
41
  try:
42
42
  from importlib import import_module
43
43
  except ImportError as x: # Python 2.6-
@@ -125,8 +125,9 @@ class _NamedEnum_RO(dict):
125
125
  raise LazyAttributeError(t, txt=_doesn_t_exist_)
126
126
 
127
127
  def __setattr__(self, attr, value): # PYCHOK no cover
128
- t = _EQUALSPACED_(self._DOT_(attr), repr(value))
129
- raise LazyAttributeError(_immutable_, txt=t)
128
+ e = _ALL_MODS.errors
129
+ raise e._ImmutableError(self, attr, value,
130
+ Error=LazyAttributeError)
130
131
 
131
132
  def enums(self):
132
133
  # Yield all C{(mod_, tuple)} pairs
@@ -200,10 +201,10 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
200
201
  'EasNorAziRk4Tuple', 'EasNorAziRkEqu6Tuple', 'LatLonAziRk4Tuple'),
201
202
  constants=_a('DIG', 'EPS', 'EPS0', 'EPS02', 'EPS1', 'EPS2', 'EPS4', 'EPS_2',
202
203
  'INF', 'INT0', 'MANT_DIG', 'MAX', 'MAX_EXP', 'MIN', 'MIN_EXP', 'NAN', 'NEG0', 'NINF',
203
- 'PI', 'PI2', 'PI_2', 'PI3', 'PI_3', 'PI3_2', 'PI4', 'PI_4',
204
+ 'PI', 'PI2', 'PI_2', 'PI3', 'PI_3', 'PI3_2', 'PI4', 'PI_4', 'PI_6',
204
205
  'R_FM', 'R_GM', 'R_KM', 'R_M', 'R_MA', 'R_MB', 'R_NM', 'R_QM', 'R_SM', 'R_VM',
205
206
  'float_', 'float0_', 'isclose', 'isfinite', 'isinf', 'isint0',
206
- 'isnan', 'isnear0', 'isnear1', 'isnear90', 'isneg0', 'isninf', 'isnon0',
207
+ 'isnan', 'isnear0', 'isnear1', 'isnear90', 'isneg', 'isneg0', 'isninf', 'isnon0',
207
208
  'remainder'),
208
209
  datums=_a('Datum', 'Datums', 'Transform', 'Transforms'),
209
210
  # deprecated=_a(), # module only
@@ -214,8 +215,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
214
215
  'bearingDMS', 'clipDegrees', 'clipRadians', 'compassDMS', 'compassPoint',
215
216
  'degDMS', 'latDMS', 'latlonDMS', 'latlonDMS_', 'lonDMS', 'normDMS',
216
217
  'parseDDDMMSS', 'parseDMS', 'parseDMS2', 'parse3llh', 'parseRad', 'precision', 'toDMS'),
217
- ecef=_a('EcefError', 'EcefFarrell21', 'EcefFarrell22', 'EcefKarney', 'EcefMatrix',
218
- 'EcefSudano', 'Ecef9Tuple', 'EcefVeness', 'EcefYou'),
218
+ ecef=_a('EcefFarrell21', 'EcefFarrell22', 'EcefKarney', 'EcefSudano', 'EcefUPC', 'EcefVeness', 'EcefYou',
219
+ 'EcefError', 'EcefMatrix', 'Ecef9Tuple'),
219
220
  ecefLocals=_a(), # module only
220
221
  elevations=_a('Elevation2Tuple', 'GeoidHeight2Tuple',
221
222
  'elevation2', 'geoidHeight2'),
@@ -357,11 +358,11 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
357
358
  'Radius_', 'Scalar', 'Scalar_', 'Zone'),
358
359
  unitsBase=_a('Float', 'Int', 'Radius', 'Str'),
359
360
  ups=_a('Ups', 'UPSError', 'parseUPS5', 'toUps8', 'upsZoneBand5'),
360
- utily=_a('acos1', 'acre2ha', 'acre2m2', 'asin1', 'atan1', 'atan1d', 'atan2', 'atan2b', 'atan2d',
361
+ utily=_a('acos1', 'acre2ha', 'acre2m2', 'agdf', 'asin1', 'atan1', 'atan1d', 'atan2', 'atan2b', 'atan2d',
361
362
  'chain2m', 'circle4', 'cot', 'cot_', 'cotd', 'cotd_',
362
363
  'degrees', 'degrees90', 'degrees180', 'degrees360', 'degrees2grades', 'degrees2m',
363
364
  'fathom2m', 'ft2m', 'furlong2m', # 'degrees2grades as degrees2gons',
364
- 'grades', 'grades400', 'grades2degrees', 'grades2radians',
365
+ 'gdf', 'grades', 'grades400', 'grades2degrees', 'grades2radians',
365
366
  # 'grades as gons', 'grades400 as gons400', 'grades2degrees as gons2degrees', 'grades2radians as gons2radians',
366
367
  'ha2acre', 'ha2m2', 'hav', 'km2m',
367
368
  'm2acre', 'm2chain', 'm2degrees', 'm2fathom', 'm2ft', 'm2furlong',
@@ -510,7 +511,7 @@ class _ALL_MODS(_internals._MODS_Base):
510
511
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
511
512
 
512
513
  __all__ = _ALL_LAZY.lazily
513
- __version__ = '25.05.19'
514
+ __version__ = '25.09.09'
514
515
 
515
516
 
516
517
  def _ALL_OTHER(*objs):
pygeodesy/lcc.py CHANGED
@@ -24,10 +24,10 @@ and John P. Snyder U{'Map Projections - A Working Manual'<https://Pubs.USGS.gov/
24
24
  # make sure int/int division yields float quotient, see .basics
25
25
  from __future__ import division as _; del _ # noqa: E702 ;
26
26
 
27
- from pygeodesy.basics import copysign0, _isin, _xinstanceof, _xsubclassof, \
28
- typename
29
- from pygeodesy.constants import EPS, EPS02, PI_2, _float as _F, _0_0, _0_5, \
30
- _1_0, _2_0, _90_0
27
+ from pygeodesy.basics import copysign0, _isin, typename, \
28
+ _xinstanceof, _xsubclassof
29
+ from pygeodesy.constants import EPS, EPS02, PI_2, _float as _F, \
30
+ _0_0, _0_5, _1_0, _2_0, _90_0
31
31
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
32
32
  from pygeodesy.datums import Datums, _ellipsoidal_datum
33
33
  from pygeodesy.errors import _IsnotError, _ValueError
@@ -50,7 +50,7 @@ from pygeodesy.utily import atan1, degrees90, degrees180, sincos2, tanPI_2_2
50
50
  from math import atan, fabs, log, radians, sin, sqrt
51
51
 
52
52
  __all__ = _ALL_LAZY.lcc
53
- __version__ = '25.05.26'
53
+ __version__ = '25.08.31'
54
54
 
55
55
  _E0_ = 'E0'
56
56
  _N0_ = 'N0'
pygeodesy/named.py CHANGED
@@ -16,17 +16,17 @@ standard Python C{namedtuple}s.
16
16
  from pygeodesy.basics import isbool, isidentifier, iskeyword, isstr, itemsorted, \
17
17
  len2, _xcopy, _xdup, _xinstanceof, _xsubclassof, _zip
18
18
  # from pygeodesy.ecef import EcefKarney # _MODS
19
- from pygeodesy.errors import _AssertionError, _AttributeError, _incompatible, \
20
- _IndexError, _KeyError, LenError, _NameError, \
21
- _NotImplementedError, _TypeError, _TypesError, \
22
- _UnexpectedError, UnitError, _ValueError, \
19
+ from pygeodesy.errors import _AssertionError, _AttributeError, _ImmutableError, \
20
+ _incompatible, _IndexError, _KeyError, LenError, \
21
+ _NameError, _NotImplementedError, _TypeError, \
22
+ _TypesError, _UnexpectedError, UnitError, _ValueError, \
23
23
  _xattr, _xkwds, _xkwds_item2, _xkwds_pop2
24
24
  from pygeodesy.internals import _caller3, _envPYGEODESY, _isPyPy, _sizeof, \
25
25
  typename, _under
26
26
  from pygeodesy.interns import MISSING, NN, _AT_, _COLON_, _COLONSPACE_, _COMMA_, \
27
27
  _COMMASPACE_, _DNAME_, _doesn_t_exist_, _DOT_, _DUNDER_, \
28
- _EQUAL_, _exists_, _immutable_, _name_, _NL_, _NN_, \
29
- _no_, _other_, _s_, _SPACE_, _std_, _UNDER_, _vs_
28
+ _EQUAL_, _exists_, _name_, _NL_, _NN_, _no_, _other_, \
29
+ _s_, _SPACE_, _std_, _UNDER_, _vs_
30
30
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
31
31
  from pygeodesy.props import _allPropertiesOf_n, deprecated_method, _hasProperty, \
32
32
  _update_all, property_doc_, Property_RO, property_RO, \
@@ -35,11 +35,10 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
35
35
  # from pygeodesy.units import _toUnit # _MODS
36
36
 
37
37
  __all__ = _ALL_LAZY.named
38
- __version__ = '25.04.28'
38
+ __version__ = '25.09.04'
39
39
 
40
40
  _COMMANL_ = _COMMA_ + _NL_
41
41
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
42
- _del_ = 'del'
43
42
  _item_ = 'item'
44
43
  _MRO_ = 'MRO'
45
44
  # __DUNDER gets mangled in class
@@ -111,7 +110,7 @@ class ADict(dict):
111
110
  self._iteration = iteration
112
111
  if items:
113
112
  dict.update(self, items)
114
- return self # in RhumbLineBase.Intersecant2, _PseudoRhumbLine.Position
113
+ return self # in RhumbLineBase.Intersecant2, _PseudoRhumbLine.Position, ...
115
114
 
116
115
  def _toL(self):
117
116
  '''(INTERNAL) Get items as list.
@@ -977,8 +976,7 @@ class _NamedTuple(tuple, _Named):
977
976
  @note: Items can not be deleted.
978
977
  '''
979
978
  if name in self._Names_:
980
- t = _SPACE_(_del_, self._DOT_(name))
981
- raise _TypeError(t, txt=_immutable_)
979
+ raise _ImmutableError(self, name) # _del_
982
980
  elif name in (_name_, _name):
983
981
  _Named.__setattr__(self, name, NN) # XXX _Named.name.fset(self, NN)
984
982
  else:
@@ -1011,8 +1009,7 @@ class _NamedTuple(tuple, _Named):
1011
1009
  '''Set attribute or item B{C{name}} to B{C{value}}.
1012
1010
  '''
1013
1011
  if name in self._Names_:
1014
- t = Fmt.EQUALSPACED(self._DOT_(name), repr(value))
1015
- raise _TypeError(t, txt=_immutable_)
1012
+ raise _ImmutableError(self, name, value)
1016
1013
  elif name in (_name_, _name):
1017
1014
  _Named.__setattr__(self, name, value) # XXX _Named.name.fset(self, value)
1018
1015
  else: # e.g. _iteration
pygeodesy/nvectorBase.py CHANGED
@@ -38,7 +38,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
38
38
  from math import degrees, fabs, sqrt
39
39
 
40
40
  __all__ = _ALL_LAZY.nvectorBase
41
- __version__ = '25.05.12'
41
+ __version__ = '25.08.18'
42
42
 
43
43
 
44
44
  class NvectorBase(Vector3d): # XXX kept private
@@ -355,7 +355,7 @@ class NvectorBase(Vector3d): # XXX kept private
355
355
  return self.xyz.to4Tuple(self.h)
356
356
 
357
357
 
358
- class _N_vector_(NvectorBase):
358
+ class _N_Vector(NvectorBase):
359
359
  '''(INTERNAL) Minimal, low-overhead C{n-vector}.
360
360
  '''
361
361
  def __init__(self, x, y, z, h=0, **name):
@@ -366,8 +366,8 @@ class _N_vector_(NvectorBase):
366
366
  self.name = name
367
367
 
368
368
 
369
- NorthPole = _N_vector_(0, 0, +1, name='NorthPole') # North pole
370
- SouthPole = _N_vector_(0, 0, -1, name='SouthPole') # South pole
369
+ NorthPole = _N_Vector(0, 0, +1, name='NorthPole') # North pole
370
+ SouthPole = _N_Vector(0, 0, -1, name='SouthPole') # South pole
371
371
 
372
372
 
373
373
  class LatLonNvectorBase(LatLonBase):
@@ -9,7 +9,7 @@ u'''Package of lazily imported C{rhumb} modules L{rhumb.aux_}, L{rhumb.ekx} and
9
9
  from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER, _lazy_import_as, _unLazy0
10
10
 
11
11
  __all__ = _ALL_LAZY.rhumb
12
- __version__ = '25.04.14'
12
+ __version__ = '25.08.28'
13
13
 
14
14
  if _unLazy0: # or _isfrozen
15
15
  from pygeodesy.rhumb.aux_ import RhumbAux, RhumbLineAux
pygeodesy/rhumb/aux_.py CHANGED
@@ -48,7 +48,7 @@ from pygeodesy.rhumb.bases import RhumbBase, RhumbLineBase, \
48
48
  from math import ceil as _ceil, fabs, radians
49
49
 
50
50
  __all__ = _ALL_LAZY.rhumb_aux_
51
- __version__ = '25.05.12'
51
+ __version__ = '25.08.31'
52
52
 
53
53
  # DIGITS = (sizeof(real) * 8) bits
54
54
  # = (ctypes.sizeof(ctypes.c_double(1.0)) * 8) bits
pygeodesy/rhumb/bases.py CHANGED
@@ -732,8 +732,7 @@ class RhumbLineBase(_CapsBase):
732
732
  azi02=other.azi12, a02=t.a12, s02=t.s12,
733
733
  at=other.azi12 - self.azi12, iteration=i)
734
734
  except Exception as x:
735
- raise IntersectionError(self, other, tol=tol,
736
- eps=eps, cause=x)
735
+ raise IntersectionError(self, other, tol=tol, cause=x, **eps)
737
736
  return P
738
737
 
739
738
  def Inverse(self, lat2, lon2, wrap=False, **outmask):
@@ -870,19 +869,19 @@ class RhumbLineBase(_CapsBase):
870
869
  P = self.Intersection(rl, tol=tol, eps=eps)
871
870
 
872
871
  else: # C{rhumb-intercept}
873
- E = self.ellipsoid
874
- _gI = E.geodesic_(exact=exact).Inverse
875
- gm = Cs.STANDARD | Cs._REDUCEDLENGTH_GEODESICSCALE # ^ Cs.DISTANCE_IN
872
+ E = self.ellipsoid
873
+ _gI = E.geodesic_(exact=exact).Inverse
874
+ gm = Cs.STANDARD | Cs._REDUCEDLENGTH_GEODESICSCALE # ^ Cs.DISTANCE_IN
875
+ _d2 = _diff182
876
876
  if est is None: # get an estimate from the "perpendicular" geodesic
877
877
  r = _gI(self.lat1, self.lon1, lat0, lon0, outmask=Cs.AZIMUTH_DISTANCE)
878
- d, _ = _diff182(r.azi2, self.azi12, K_2_0=True)
878
+ d, _ = _d2(r.azi2, self.azi12, K_2_0=True)
879
879
  _, s12 = sincos2d(d)
880
880
  s12 *= r.s12 # signed
881
881
  else:
882
882
  s12 = Meter(est=est)
883
883
  try:
884
884
  _abs = fabs
885
- _d2 = _diff182
886
885
  _ErT = E.rocPrimeVertical # aka rocTransverse
887
886
  _ovr = _over
888
887
  _S12 = Fsum(s12).fsum2f_
@@ -894,7 +893,7 @@ class RhumbLineBase(_CapsBase):
894
893
  s, c, s2, c2 = _scd(d, r.lat2)
895
894
  c2 *= _ErT(r.lat2)
896
895
  s *= _ovr(s2 * self._salp, c2) - _ovr(s * r.M21, r.m12)
897
- s12, t = _S12(c / s) # XXX _ovr?
896
+ s12, t = _S12(c / s) if s else (s12, s) # XXX _ovr?
898
897
  if _abs(t) < tol: # or _abs(c) < EPS
899
898
  break
900
899
  P.set_(azi0=r.azi1, a02=r.a12, s02=r.s12, # azi2=r.azi2,
pygeodesy/rhumb/ekx.py CHANGED
@@ -22,9 +22,9 @@ License. For more information, see the U{GeographicLib<https://GeographicLib.So
22
22
  # make sure int/int division yields float quotient
23
23
  from __future__ import division as _; del _ # noqa: E702 ;
24
24
 
25
- from pygeodesy.basics import copysign0, neg
26
- from pygeodesy.constants import PI_2, _0_0s, _0_0, _0_5, _1_0, \
27
- _2_0, _4_0, _720_0, _over, _1_over
25
+ # from pygeodesy.basics import copysign0, neg # _MODS
26
+ from pygeodesy.constants import PI_2, _over, _1_over, _0_0s, \
27
+ _0_0, _0_5, _1_0, _2_0, _4_0, _720_0
28
28
  # from pygeodesy.datums import _WGS84 # from .rhumb.bases
29
29
  # from pygeodesy.deprecated import RhumbOrder2Tuple # _MODS
30
30
  from pygeodesy.errors import RhumbError, _xkwds_pop2, _Xorder
@@ -42,7 +42,7 @@ from pygeodesy.utily import atan1, sincos2_
42
42
  from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan # as _tan
43
43
 
44
44
  __all__ = _ALL_LAZY.rhumb_ekx
45
- __version__ = '25.05.12'
45
+ __version__ = '25.08.31'
46
46
 
47
47
 
48
48
  class Rhumb(RhumbBase):
@@ -159,9 +159,9 @@ class Rhumb(RhumbBase):
159
159
  if (outmask & Cs.DISTANCE):
160
160
  a = s = hypot(lon12, psi12)
161
161
  if a:
162
- a *= self._DIsometric2Rectifyingd(psi2, psi1)
163
- s = self._mpd * a # == E._Lpd
164
- a = copysign0(a, s)
162
+ a *= self._DIsometric2Rectifyingd(psi2, psi1)
163
+ s = self._mpd * a # == E._Lpd
164
+ a = _MODS.basics.copysign0(a, s)
165
165
  r.set_(a12=a, s12=s)
166
166
 
167
167
  if ((outmask | self._debug) & Cs._DEBUG_INVERSE): # PYCHOK no cover
@@ -306,7 +306,7 @@ class RhumbLine(RhumbLineBase):
306
306
 
307
307
  @Property_RO
308
308
  def _psi1(self):
309
- '''(INTERNAL) Get the I{isometric auxiliary} latitude C{psi} (C{degrees}).
309
+ '''(INTERNAL) Get the I{isometric auxiliary} latitude (C{degrees}).
310
310
  '''
311
311
  return self.ellipsoid.auxIsometric(self.lat1)
312
312
 
@@ -465,7 +465,7 @@ def _sincosSeries(sinp, x, y, C, n):
465
465
  # SC = sinp ? sin : cos
466
466
  # CS = sinp ? cos : sin
467
467
  # ...
468
- d, _neg = (x - y), neg
468
+ d, _neg = (x - y), _MODS.basics.neg
469
469
  sp, cp, sd, cd = sincos2_(x + y, d)
470
470
  sd = (sd / d) if d else _1_0
471
471
  s = _neg(sp * sd) # negative
pygeodesy/solveBase.py CHANGED
@@ -23,7 +23,7 @@ from pygeodesy.units import Precision_
23
23
  from pygeodesy.utily import unroll180
24
24
 
25
25
  __all__ = _ALL_LAZY.solveBase
26
- __version__ = '25.05.12'
26
+ __version__ = '25.09.02'
27
27
 
28
28
  _ERROR_ = 'ERROR'
29
29
 
@@ -63,10 +63,16 @@ class _SolveCapsBase(_CapsBase):
63
63
 
64
64
  @Property_RO
65
65
  def a(self):
66
- '''Get the I{equatorial} radius, semi-axis (C{meter}).
66
+ '''Get the ellipsoid's I{equatorial} radius, semi-axis (C{meter}).
67
67
  '''
68
68
  return self.ellipsoid.a
69
69
 
70
+ @Property_RO
71
+ def b(self):
72
+ '''Get the ellipsoid's I{polar} radius, semi-axis (C{meter}).
73
+ '''
74
+ return self.ellipsoid.b
75
+
70
76
  @property_RO
71
77
  def _cmdBasic(self): # PYCHOK no covers '''(INTERNAL) I{Must be overloaded}.'''
72
78
  notOverloaded(self, underOK=True)
@@ -381,6 +387,11 @@ class _SolveGDictBase(_SolveBase):
381
387
  if path:
382
388
  self._setXable(path)
383
389
 
390
+ def ArcDirect(self, lat1, lon1, azi1, a12, outmask=_UNUSED_): # PYCHOK unused
391
+ '''Return the C{Direct} result at C{a12} degrees.
392
+ '''
393
+ return self._GDictDirect(lat1, lon1, azi1, True, a12)
394
+
384
395
  @Property_RO
385
396
  def _cmdDirect(self):
386
397
  '''(INTERNAL) Get the C{Solve} I{Direct} cmd (C{tuple}).
@@ -394,7 +405,7 @@ class _SolveGDictBase(_SolveBase):
394
405
  return self._cmdBasic + ('-i',)
395
406
 
396
407
  def Direct(self, lat1, lon1, azi1, s12, outmask=_UNUSED_): # PYCHOK unused
397
- '''Return the C{Direct} result.
408
+ '''Return the C{Direct} result at distance C{s12}.
398
409
  '''
399
410
  return self._GDictDirect(lat1, lon1, azi1, False, s12)
400
411
 
@@ -17,9 +17,9 @@ U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}.
17
17
  from __future__ import division as _; del _ # noqa: E702 ;
18
18
 
19
19
  from pygeodesy.basics import copysign0, _isin, map1, signOf, typename
20
- from pygeodesy.constants import EPS, EPS1, EPS4, PI, PI2, PI_2, PI_4, R_M, \
21
- isnear0, isnear1, isnon0, _0_0, _0_5, \
22
- _1_0, _2_0, _90_0
20
+ from pygeodesy.constants import EPS, EPS1, EPS4, PI, PI2, PI_2, PI_4, \
21
+ R_M, _0_0, _0_5, _1_0, _2_0, _90_0, \
22
+ isnear0, isnear1, isnon0
23
23
  from pygeodesy.datums import _ellipsoidal_datum, _mean_radius
24
24
  from pygeodesy.errors import _AssertionError, CrossError, crosserrors, \
25
25
  _TypeError, _ValueError, IntersectionError, \
@@ -36,7 +36,7 @@ from pygeodesy.interns import _1_, _2_, _coincident_, _composite_, _colinear_, \
36
36
  _point_, _SPACE_, _too_
37
37
  from pygeodesy.latlonBase import _trilaterate5
38
38
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _ALL_OTHER
39
- # from pygeodesy.nvectorBase import NvectorBase, sumOf # _MODS
39
+ # from pygeodesy.nvectorBase import _N_Vector, NvectorBase, sumOf # _MODS
40
40
  from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, NearestOn3Tuple, \
41
41
  Triangle7Tuple, Triangle8Tuple
42
42
  from pygeodesy.points import ispolar, nearestOn5 as _nearestOn5, \
@@ -57,7 +57,7 @@ from pygeodesy.vector3d import sumOf, Vector3d
57
57
  from math import asin, cos, degrees, fabs, radians, sin
58
58
 
59
59
  __all__ = _ALL_LAZY.sphericalTrigonometry
60
- __version__ = '25.05.28'
60
+ __version__ = '25.08.31'
61
61
 
62
62
  _PI_EPS4 = PI - EPS4
63
63
  if _PI_EPS4 >= PI:
@@ -968,10 +968,10 @@ def _intersect(start1, end1, start2, end2, height=None, wrap=False, # in.ellips
968
968
  a, b = antipode_(a, b) # PYCHOK PhiLam2Tuple
969
969
 
970
970
  else: # end point(s) or bearing(s)
971
- _N_vector_ = _MODS.nvectorBase._N_vector_
971
+ _N = _MODS.nvectorBase._N_Vector
972
972
 
973
- x1, d1 = _int3d2(s1, end1, wrap, _1_, _N_vector_, hs)
974
- x2, d2 = _int3d2(s2, end2, wrap, _2_, _N_vector_, hs)
973
+ x1, d1 = _int3d2(s1, end1, wrap, _1_, _N, hs)
974
+ x2, d2 = _int3d2(s2, end2, wrap, _2_, _N, hs)
975
975
  x = x1.cross(x2)
976
976
  if x.length < EPS: # [nearly] colinear or parallel lines
977
977
  raise IntersectionError(_colinear_)