pygeodesy 25.5.5__py2.py3-none-any.whl → 25.5.28__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 (88) hide show
  1. pygeodesy/__init__.py +186 -186
  2. pygeodesy/__main__.py +4 -3
  3. pygeodesy/albers.py +4 -4
  4. pygeodesy/auxilats/_CX_Rs.py +3 -3
  5. pygeodesy/auxilats/auxAngle.py +2 -2
  6. pygeodesy/auxilats/auxDLat.py +2 -2
  7. pygeodesy/auxilats/auxDST.py +2 -2
  8. pygeodesy/auxilats/auxLat.py +2 -2
  9. pygeodesy/auxilats/auxily.py +2 -2
  10. pygeodesy/azimuthal.py +2 -2
  11. pygeodesy/booleans.py +11 -11
  12. pygeodesy/cartesianBase.py +2 -2
  13. pygeodesy/clipy.py +2 -2
  14. pygeodesy/constants.py +7 -7
  15. pygeodesy/css.py +1 -1
  16. pygeodesy/datums.py +2 -2
  17. pygeodesy/deprecated/__init__.py +8 -8
  18. pygeodesy/deprecated/bases.py +2 -2
  19. pygeodesy/deprecated/rhumbBase.py +2 -2
  20. pygeodesy/deprecated/rhumbaux.py +2 -2
  21. pygeodesy/deprecated/rhumbsolve.py +2 -2
  22. pygeodesy/deprecated/rhumbx.py +2 -2
  23. pygeodesy/ecef.py +3 -4
  24. pygeodesy/ellipsoidalBase.py +2 -2
  25. pygeodesy/ellipsoidalBaseDI.py +7 -6
  26. pygeodesy/ellipsoidalExact.py +24 -29
  27. pygeodesy/ellipsoidalGeodSolve.py +19 -19
  28. pygeodesy/ellipsoidalKarney.py +22 -27
  29. pygeodesy/ellipsoidalNvector.py +4 -4
  30. pygeodesy/ellipsoidalVincenty.py +17 -15
  31. pygeodesy/ellipsoids.py +4 -4
  32. pygeodesy/elliptic.py +16 -11
  33. pygeodesy/errors.py +1 -1
  34. pygeodesy/etm.py +2 -2
  35. pygeodesy/fmath.py +9 -9
  36. pygeodesy/formy.py +2 -2
  37. pygeodesy/frechet.py +6 -6
  38. pygeodesy/fstats.py +2 -2
  39. pygeodesy/fsums.py +37 -28
  40. pygeodesy/gars.py +2 -3
  41. pygeodesy/geodesici.py +4 -4
  42. pygeodesy/geodesicw.py +27 -8
  43. pygeodesy/geodesicx/__init__.py +3 -3
  44. pygeodesy/geodesicx/gx.py +52 -48
  45. pygeodesy/geodesicx/gxarea.py +54 -65
  46. pygeodesy/geodesicx/gxbases.py +12 -2
  47. pygeodesy/geodesicx/gxline.py +10 -7
  48. pygeodesy/geoids.py +6 -6
  49. pygeodesy/hausdorff.py +5 -5
  50. pygeodesy/heights.py +5 -5
  51. pygeodesy/internals.py +2 -2
  52. pygeodesy/interns.py +5 -5
  53. pygeodesy/iters.py +1 -1
  54. pygeodesy/karney.py +28 -12
  55. pygeodesy/ktm.py +2 -2
  56. pygeodesy/latlonBase.py +3 -4
  57. pygeodesy/lazily.py +1 -1
  58. pygeodesy/lcc.py +3 -3
  59. pygeodesy/ltp.py +5 -5
  60. pygeodesy/mgrs.py +3 -3
  61. pygeodesy/namedTuples.py +3 -3
  62. pygeodesy/nvectorBase.py +2 -2
  63. pygeodesy/osgr.py +2 -2
  64. pygeodesy/points.py +2 -3
  65. pygeodesy/props.py +18 -18
  66. pygeodesy/resections.py +30 -24
  67. pygeodesy/rhumb/aux_.py +2 -2
  68. pygeodesy/rhumb/bases.py +3 -3
  69. pygeodesy/rhumb/ekx.py +3 -4
  70. pygeodesy/rhumb/solve.py +2 -2
  71. pygeodesy/simplify.py +2 -2
  72. pygeodesy/solveBase.py +2 -2
  73. pygeodesy/sphericalBase.py +8 -8
  74. pygeodesy/sphericalNvector.py +19 -16
  75. pygeodesy/sphericalTrigonometry.py +24 -24
  76. pygeodesy/trf.py +4 -4
  77. pygeodesy/triaxials.py +2 -2
  78. pygeodesy/units.py +7 -8
  79. pygeodesy/utily.py +2 -2
  80. pygeodesy/utmupsBase.py +2 -2
  81. pygeodesy/vector2d.py +14 -8
  82. pygeodesy/vector3d.py +3 -3
  83. pygeodesy/webmercator.py +2 -2
  84. {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/METADATA +16 -16
  85. pygeodesy-25.5.28.dist-info/RECORD +119 -0
  86. pygeodesy-25.5.5.dist-info/RECORD +0 -119
  87. {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/WHEEL +0 -0
  88. {pygeodesy-25.5.5.dist-info → pygeodesy-25.5.28.dist-info}/top_level.txt +0 -0
pygeodesy/latlonBase.py CHANGED
@@ -25,9 +25,8 @@ from pygeodesy.errors import _AttributeError, IntersectionError, \
25
25
  # from pygeodesy.fmath import favg # _MODS
26
26
  # from pygeodesy import formy as _formy # _MODS.into
27
27
  from pygeodesy.internals import _passarg, typename
28
- from pygeodesy.interns import NN, _COMMASPACE_, _concentric_, _height_, \
29
- _intersection_, _LatLon_, _m_, _negative_, \
30
- _no_, _overlap_, _too_, _point_ # PYCHOK used!
28
+ from pygeodesy.interns import NN, _COMMASPACE_, _concentric_, _intersection_, \
29
+ _LatLon_, _m_, _no_, _overlap_, _point_ # PYCHOK used!
31
30
  # from pygeodesy.iters import PointsIter, points2 # _MODS
32
31
  # from pygeodesy.karney import Caps # _MODS
33
32
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
@@ -49,7 +48,7 @@ from contextlib import contextmanager
49
48
  from math import asin, cos, degrees, fabs, radians
50
49
 
51
50
  __all__ = _ALL_LAZY.latlonBase
52
- __version__ = '25.04.28'
51
+ __version__ = '25.05.07'
53
52
 
54
53
  _formy = _MODS.into(formy=__name__)
55
54
 
pygeodesy/lazily.py CHANGED
@@ -510,7 +510,7 @@ class _ALL_MODS(_internals._MODS_Base):
510
510
  _internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
511
511
 
512
512
  __all__ = _ALL_LAZY.lazily
513
- __version__ = '25.04.30'
513
+ __version__ = '25.05.19'
514
514
 
515
515
 
516
516
  def _ALL_OTHER(*objs):
pygeodesy/lcc.py CHANGED
@@ -22,7 +22,7 @@ and John P. Snyder U{'Map Projections - A Working Manual'<https://Pubs.USGS.gov/
22
22
  @var Conics.WRF_Lb: Conic(name='WRF_Lb', lat0=40, lon0=-97, par1=33, par2=45, E0=0, N0=0, k0=1, SP=2, datum=Datum(name='WGS84', ellipsoid=Ellipsoids.WGS84, transform=Transforms.WGS84)
23
23
  '''
24
24
  # make sure int/int division yields float quotient, see .basics
25
- from __future__ import division as _; del _ # PYCHOK semicolon
25
+ from __future__ import division as _; del _ # noqa: E702 ;
26
26
 
27
27
  from pygeodesy.basics import copysign0, _isin, _xinstanceof, _xsubclassof, \
28
28
  typename
@@ -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.04.14'
53
+ __version__ = '25.05.26'
54
54
 
55
55
  _E0_ = 'E0'
56
56
  _N0_ = 'N0'
@@ -457,7 +457,7 @@ class Lcc(_NamedBase):
457
457
  # h=self.height, conic=self.conic,
458
458
  # name=self._name__(name))
459
459
  # args, kwds = _args_kwds(**kwds)
460
- # return self.__class__(*args, **kwds) # .classof
460
+ # return type(self)(*args, **kwds) # .classof
461
461
 
462
462
  @Property_RO
463
463
  def easting(self):
pygeodesy/ltp.py CHANGED
@@ -11,7 +11,7 @@ and L{ChLVe} and L{Ltp}, L{ChLV}, L{LocalError}, L{Attitude} and L{Frustum}.
11
11
  <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1LocalCartesian.html>}.
12
12
  '''
13
13
  # make sure int/int division yields float quotient, see .basics
14
- from __future__ import division as _; del _ # PYCHOK semicolon
14
+ from __future__ import division as _; del _ # noqa: E702 ;
15
15
 
16
16
  from pygeodesy.basics import _args_kwds_names, _isin, map1, map2, _xinstanceof, \
17
17
  _xsubclassof, typename # .datums
@@ -45,7 +45,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
45
45
  # from math import fabs, floor as _floor # from .fmath, .fsums
46
46
 
47
47
  __all__ = _ALL_LAZY.ltp
48
- __version__ = '25.05.01'
48
+ __version__ = '25.05.12'
49
49
 
50
50
  _height0_ = _height_ + _0_
51
51
  _narrow_ = 'narrow'
@@ -306,11 +306,11 @@ class Frustum(_NamedBase):
306
306
  # left and right corners, or swapped
307
307
  if r < EPS: # no roll
308
308
  r = a * tan_h_2
309
- l = -r # PYCHOK l is ell
309
+ l = -r # noqa: E741 l is ell
310
310
  else: # roll
311
- r, l = tand_(r - h_2, r + h_2, roll_hfov=r) # PYCHOK l is ell
311
+ r, l = tand_(r - h_2, r + h_2, roll_hfov=r) # noqa: E741 l is ell
312
312
  r *= -a # negate right positive
313
- l *= -a # PYCHOK l is ell
313
+ l *= -a # noqa: E741 l is ell
314
314
  y = a * cotd(e, tilt_vfov=e)
315
315
  return (l, y), (r, y)
316
316
 
pygeodesy/mgrs.py CHANGED
@@ -36,7 +36,7 @@ and compare the MGRS results with those from I{Karney}'s utility U{GeoConvert
36
36
  '''
37
37
 
38
38
  from pygeodesy.basics import halfs2, _isin, _splituple, _xinstanceof
39
- # from pygeodesy.constants import _0_5 # from .units
39
+ from pygeodesy.constants import _0_5
40
40
  from pygeodesy.datums import _ellipsoidal_datum, _WGS84
41
41
  from pygeodesy.errors import _AssertionError, MGRSError, _parseX, \
42
42
  _ValueError, _xkwds
@@ -49,14 +49,14 @@ from pygeodesy.named import _name2__, _NamedBase, _NamedTuple, _Pass
49
49
  from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple
50
50
  from pygeodesy.props import deprecated_property_RO, property_RO, Property_RO
51
51
  from pygeodesy.streprs import enstr2, _enstr2m3, Fmt, _resolution10, _xzipairs
52
- from pygeodesy.units import Easting, Northing, Str, _100km, _0_5
52
+ from pygeodesy.units import Easting, Northing, Str, _100km
53
53
  from pygeodesy.units import _1um, _2000km # PYCHOK used!
54
54
  from pygeodesy.ups import _hemi, toUps8, Ups, _UPS_ZONE
55
55
  from pygeodesy.utm import toUtm8, _to3zBlat, Utm, _UTM_ZONE_MAX, _UTM_ZONE_MIN
56
56
  # from pygeodesy.utmupsBase import _UTM_ZONE_MAX, _UTM_ZONE_MIN # from .utm
57
57
 
58
58
  __all__ = _ALL_LAZY.mgrs
59
- __version__ = '25.04.14'
59
+ __version__ = '25.05.12'
60
60
 
61
61
  _AN_ = 'AN' # default south pole grid tile and band B
62
62
  _AtoPx_ = _AtoZnoIO_.tillP
pygeodesy/namedTuples.py CHANGED
@@ -10,7 +10,7 @@ of C{_NamedTuple} defined in C{pygeodesy.named}.
10
10
 
11
11
  from pygeodesy.basics import isinstanceof, issubclassof, map1, _xinstanceof
12
12
  # from pygeodesy.cartesianBase import CartesianBase # _MODS
13
- # from pygeodesy.constants import INT0 # from .units
13
+ from pygeodesy.constants import INT0
14
14
  # from pygeodesy.dms import toDMS # _MODS
15
15
  from pygeodesy.errors import _TypeError, _xattr, _xkwds, _xkwds_not
16
16
  from pygeodesy.interns import NN, _1_, _2_, _a_, _A_, _area_, _angle_, _b_, _B_, \
@@ -26,10 +26,10 @@ from pygeodesy.props import deprecated_property_RO, property_RO
26
26
  from pygeodesy.units import Band, Bearing, Degrees, Degrees2, Easting, FIx, \
27
27
  Height, Int, Lam, Lat, Lon, Meter, Meter2, \
28
28
  Northing, Number_, Phi, Precision_, Radians, \
29
- Radius, Scalar, Str, INT0
29
+ Radius, Scalar, Str
30
30
 
31
31
  __all__ = _ALL_LAZY.namedTuples
32
- __version__ = '24.11.22'
32
+ __version__ = '25.05.12'
33
33
 
34
34
  # __DUNDER gets mangled in class
35
35
  _closest_ = 'closest'
pygeodesy/nvectorBase.py CHANGED
@@ -16,7 +16,7 @@ from pygeodesy.constants import EPS, EPS0, EPS1, EPS_2, R_M, \
16
16
  # from pygeodesy.datums import _spherical_datum # from .formy
17
17
  from pygeodesy.errors import IntersectionError, _ValueError, VectorError, \
18
18
  _xattrs, _xkwds, _xkwds_pop2
19
- from pygeodesy.fmath import fdot, fidw, hypot # PYCHOK fdot shared
19
+ from pygeodesy.fmath import fidw, hypot
20
20
  from pygeodesy.fsums import Fsum, fsumf_
21
21
  from pygeodesy.formy import _isequalTo, _spherical_datum
22
22
  # from pygeodesy.internals import _under # from .named
@@ -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.04.14'
41
+ __version__ = '25.05.12'
42
42
 
43
43
 
44
44
  class NvectorBase(Vector3d): # XXX kept private
pygeodesy/osgr.py CHANGED
@@ -24,7 +24,7 @@ U{A Guide<https://www.OrdnanceSurvey.co.UK/documents/resources/guide-coordinate-
24
24
  and U{Ordnance Survey National Grid<https://WikiPedia.org/wiki/Ordnance_Survey_National_Grid>}.
25
25
  '''
26
26
  # make sure int/int division yields float quotient, see .basics
27
- from __future__ import division as _; del _ # PYCHOK semicolon
27
+ from __future__ import division as _; del _ # noqa: E702 ;
28
28
 
29
29
  from pygeodesy.basics import halfs2, isbool, isfloat, map1, \
30
30
  _splituple, _xsubclassof, typename
@@ -54,7 +54,7 @@ from pygeodesy.utily import degrees90, degrees180, sincostan3, truncate
54
54
  from math import cos, fabs, radians, sin, sqrt
55
55
 
56
56
  __all__ = _ALL_LAZY.osgr
57
- __version__ = '25.04.12'
57
+ __version__ = '25.05.12'
58
58
 
59
59
  _equivalent_ = 'equivalent'
60
60
  _OSGR_ = 'OSGR'
pygeodesy/points.py CHANGED
@@ -52,8 +52,7 @@ from pygeodesy.named import classname, _NamedTuple, nameof, \
52
52
  notImplemented, notOverloaded
53
53
  from pygeodesy.namedTuples import Bounds2Tuple, Bounds4Tuple, LatLon2Tuple, \
54
54
  NearestOn3Tuple, NearestOn5Tuple, \
55
- Point3Tuple, Vector3Tuple, \
56
- PhiLam2Tuple # PYCHOK shared
55
+ Point3Tuple, Vector3Tuple
57
56
  from pygeodesy.props import Property_RO, property_doc_, property_RO
58
57
  from pygeodesy.streprs import Fmt, instr
59
58
  from pygeodesy.units import Number_, Radius, Scalar, Scalar_
@@ -63,7 +62,7 @@ from pygeodesy.utily import atan2b, degrees90, degrees180, degrees2m, \
63
62
  from math import cos, fabs, fmod as _fmod, radians, sin
64
63
 
65
64
  __all__ = _ALL_LAZY.points
66
- __version__ = '25.04.18'
65
+ __version__ = '25.05.12'
67
66
 
68
67
  _ilat_ = 'ilat'
69
68
  _ilon_ = 'ilon'
pygeodesy/props.py CHANGED
@@ -26,7 +26,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
26
26
  from functools import wraps as _wraps
27
27
 
28
28
  __all__ = _ALL_LAZY.props
29
- __version__ = '25.04.14'
29
+ __version__ = '25.05.26'
30
30
 
31
31
  _class_ = 'class'
32
32
  _DNL_ = _NL_ * 2 # PYCHOK used!
@@ -347,7 +347,7 @@ class property_RO(_PropertyBase):
347
347
  if Clas: # overrides inst.__class__
348
348
  d = Clas[0].__dict__.get(uname, MISSING)
349
349
  else:
350
- d = getattr(inst.__class__, uname, MISSING)
350
+ d = getattr(type(inst), uname, MISSING)
351
351
  # if d is MISSING: # XXX superfluous
352
352
  # for c in type(inst).__mro__[:-1]:
353
353
  # if uname in c.__dict__:
@@ -403,7 +403,7 @@ class property_ROver(_property_RO___):
403
403
  '''
404
404
  v = self.method(inst)
405
405
  n = self.name
406
- C = inst.__class__
406
+ C = type(inst)
407
407
  for c in C.__mro__: # [:-1]
408
408
  if getattr(c, n, None) is self:
409
409
  setattr(c, n, v) # overwrite property_ROver
@@ -460,7 +460,7 @@ def _deprecated(call, kind, qual_d):
460
460
  @see: Brett Slatkin, "Effective Python", 2019 page 105, 2nd
461
461
  ed, Addison-Wesley.
462
462
  '''
463
- doc = _DOCof(call)
463
+ doc = _DEPRECATEDof(call)
464
464
 
465
465
  @_wraps(call) # PYCHOK self?
466
466
  def _deprecated_call(*args, **kwds):
@@ -517,6 +517,17 @@ def _deprecated_module(name): # PYCHOK no cover
517
517
  _throwarning(_module_, name, _dont_use_)
518
518
 
519
519
 
520
+ def _DEPRECATEDof(obj):
521
+ '''(INTERNAL) Get uniform DEPRECATED __doc__ string.
522
+ '''
523
+ try:
524
+ d = obj.__doc__.strip()
525
+ i = d.find(_DEPRECATED_)
526
+ except AttributeError:
527
+ i = -1
528
+ return _DOT_(_DEPRECATED_, NN) if i < 0 else d[i:]
529
+
530
+
520
531
  if _WARNINGS_X_DEV:
521
532
  class deprecated_property(_PropertyBase):
522
533
  '''Decorator for a DEPRECATED C{property} or C{Property}.
@@ -524,7 +535,7 @@ if _WARNINGS_X_DEV:
524
535
  def __init__(self, method):
525
536
  '''Decorator for a DEPRECATED C{property} or C{Property} getter.
526
537
  '''
527
- doc = _DOCof(method)
538
+ doc = _DEPRECATEDof(method)
528
539
 
529
540
  def _fget(inst): # PYCHOK no cover
530
541
  '''Get the C{property} or C{Property} value.
@@ -554,7 +565,7 @@ if _WARNINGS_X_DEV:
554
565
  '''Set the C{property} or C{Property} value.
555
566
  '''
556
567
  q = _qualified(inst, self.name)
557
- _throwarning(typename(property), q, _DOCof(method))
568
+ _throwarning(typename(property), q, _DEPRECATEDof(method))
558
569
  method(inst, val)
559
570
  # self._update(inst) # un-cache this item
560
571
 
@@ -594,7 +605,7 @@ def deprecated_property_RO(method):
594
605
  def _deprecated_RO(method, _RO):
595
606
  '''(INTERNAL) Create a DEPRECATED C{property_RO} or C{Property_RO}.
596
607
  '''
597
- doc = _DOCof(method)
608
+ doc = _DEPRECATEDof(method)
598
609
 
599
610
  if _WARNINGS_X_DEV:
600
611
 
@@ -614,17 +625,6 @@ def _deprecated_RO(method, _RO):
614
625
  return _RO(method, doc=doc)
615
626
 
616
627
 
617
- def _DOCof(obj):
618
- '''(INTERNAL) Get uniform DEPRECATED __doc__ string.
619
- '''
620
- try:
621
- d = obj.__doc__.strip()
622
- i = d.find(_DEPRECATED_)
623
- except AttributeError:
624
- i = -1
625
- return _DOT_(_DEPRECATED_, NN) if i < 0 else d[i:]
626
-
627
-
628
628
  def _qualified(inst, name):
629
629
  '''(INTERNAL) Fully qualify a name.
630
630
  '''
pygeodesy/resections.py CHANGED
@@ -10,7 +10,7 @@ L{triAngle}, L{triAngle5}, L{triSide}, L{triSide2} and L{triSide4}.
10
10
  U{Pierlot<http://www.Telecom.ULg.ac.BE/publi/publications/pierlot/Pierlot2014ANewThree>}.
11
11
  '''
12
12
  # make sure int/int division yields float quotient
13
- from __future__ import division as _; del _ # PYCHOK semicolon
13
+ from __future__ import division as _; del _ # noqa: E702 ;
14
14
 
15
15
  from pygeodesy.basics import map1, map2, _zip, _ALL_LAZY, typename
16
16
  from pygeodesy.constants import EPS, EPS0, EPS02, INT0, PI, PI2, PI_2, PI_4, \
@@ -34,7 +34,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d
34
34
  from math import cos, degrees, fabs, radians, sin, sqrt
35
35
 
36
36
  __all__ = _ALL_LAZY.resections
37
- __version__ = '25.05.04'
37
+ __version__ = '25.05.12'
38
38
 
39
39
  _concyclic_ = 'concyclic'
40
40
  _PA_ = 'PA'
@@ -798,12 +798,12 @@ def triArea(a, b, c):
798
798
  try:
799
799
  r, y, x = sorted(map1(float, a, b, c))
800
800
  if r > 0: # r = min(a, b, c)
801
- z = r
802
- d = x - y
803
- r = (z + d) * (z - d)
801
+ s = r
802
+ d = x - y
803
+ r = (s + d) * (s - d)
804
804
  if r:
805
- x += y
806
- r *= (x + z) * (x - z)
805
+ y += x
806
+ r *= (y + s) * (y - s)
807
807
  if r < 0:
808
808
  raise ValueError(_negative_)
809
809
  return sqrt(r / _16_0) if r else _0_0
@@ -927,9 +927,11 @@ def triSide4(radA, radB, c):
927
927
  sc = fsum1f_(sa * cb, sb * ca)
928
928
  if sc < EPS0 or min(sa, sb) < 0:
929
929
  raise ValueError(_invalid_)
930
- sc = c / sc
931
- return TriSide4Tuple((sa * sc), (sb * sc), rC, (sa * sb * sc),
932
- name=typename(triSide4))
930
+ sc = c / sc
931
+ sa *= sc
932
+ sd = sa * sb
933
+ sb *= sc
934
+ return TriSide4Tuple(sa, sb, rC, sd, name=typename(triSide4))
933
935
 
934
936
  except (TypeError, ValueError) as x:
935
937
  raise TriangleError(radA=radA, radB=radB, c=c, cause=x)
@@ -948,7 +950,8 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
948
950
  @arg alpha: Angle subtended by triangle side B{C{b}} (C{degrees}, non-negative).
949
951
  @arg beta: Angle subtended by triangle side B{C{a}} (C{degrees}, non-negative).
950
952
  @kwarg R3: Callable to determine C{R3} from C{(R3 - C)**2 = D}, typically standard
951
- Python function C{min} or C{max}, invoked with 2 arguments.
953
+ Python function C{min} or C{max}, invoked with 2 arguments, each
954
+ C{float} or an L{Fsum<pygeodesy.fsums.Fsum>}.
952
955
 
953
956
  @return: L{Survey3Tuple}C{(PA, PB, PC)} with distance from survey point C{P} to
954
957
  each of the triangle corners C{A}, C{B} and C{C}, same units as B{C{a}},
@@ -962,19 +965,20 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
962
965
  U{Devine Proportions, page 252<http://www.MS.LT/derlius/WildbergerDivineProportions.pdf>}
963
966
  and function L{snellius3}.
964
967
  '''
965
- def _s(x):
968
+ def _sin2(x):
966
969
  return sin(x)**2
967
970
 
968
971
  def _vpa(r3, q2, q3, s2, s3):
972
+ r4 = r3 * _4_0
973
+ s4 = r4 * s2
974
+ if isnear0(s4):
975
+ raise ValueError(_coincident_)
969
976
  r1 = s2 * q3 / s3
970
- r = r1 * r3 * _4_0
971
- R = _Fsumf_(r1, r3, -q2)
972
- R *= R # -(R**2 ...
973
- R -= r # ... - r) / s3
974
- n = -R.fover(s3)
975
- if n < 0 or r < EPS0:
977
+ N2 = _Fsumf_(r1, r3, -q2)**2
978
+ n = (r4 * r1 - N2).fover(s4)
979
+ if n < 0:
976
980
  raise ValueError(_coincident_)
977
- return sqrt((n / r) * q3) if n else _0_0
981
+ return sqrt(n) if n else _0_0
978
982
 
979
983
  try:
980
984
  a, b, c, da, db = _noneg(a, b, c, alpha, beta)
@@ -983,21 +987,23 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
983
987
  raise ValueError(_coincident_)
984
988
 
985
989
  ra, rb = map1(radians, da, db)
986
- s1, s2, s3 = s = map1(_s, rb, ra, ra + rb) # rb, ra!
990
+ s1, s2, s3 = s = map1(_sin2, rb, ra, ra + rb) # rb, ra!
987
991
  if min(s) < EPS02:
988
992
  raise ValueError(_or(_coincident_, _colinear_))
993
+ s += _Fsumf_(*s), # == fsum1(s),
989
994
 
990
995
  Q = _Fsumf_(*q) # == a**2 + b**2 + ...
991
- s += _Fsumf_(*s), # == fsum1(s),
992
996
  C0 = Fdot(s, q1, q2, q3, -Q * _0_5)
993
997
  r3 = C0.fover(-s3) # C0 /= -s3
998
+
994
999
  Q *= Q # Q**2 - 2 * (a**4 + b**4 ...
995
- Q -= hypot2_(*q) *_2_0 # ... + c**4)
996
- d0 = Q.fmul(s1 * s2).fover(s3)
1000
+ Q -= hypot2_(*q) * _2_0 # ... + c**4)
1001
+ Q *= s1 * s2 # Q * s1 * s2 / s3
1002
+ d0 = Q.fover(s3)
997
1003
  if d0 > EPS02: # > c0
998
1004
  _xcallable(R3=R3)
999
1005
  d0 = sqrt(d0)
1000
- r3 = R3(float(C0 + d0), float(C0 - d0)) # XXX min or max
1006
+ r3 = R3(C0 + d0, C0 - d0).as_iscalar # XXX min or max
1001
1007
  elif d0 < (-EPS02):
1002
1008
  raise ValueError(_negative_)
1003
1009
 
pygeodesy/rhumb/aux_.py CHANGED
@@ -26,7 +26,7 @@ License. For more information, see the U{GeographicLib<https://GeographicLib.So
26
26
  windows/win32/fileio/naming-a-file#naming-conventions>} with and without extension.
27
27
  '''
28
28
  # make sure int/int division yields float quotient
29
- from __future__ import division as _; del _ # PYCHOK semicolon
29
+ from __future__ import division as _; del _ # noqa: E702 ;
30
30
 
31
31
  from pygeodesy.auxilats.auxAngle import AuxMu, AuxPhi, hypot
32
32
  from pygeodesy.auxilats.auxDLat import AuxDLat, _DClenshaw
@@ -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.04.12'
51
+ __version__ = '25.05.12'
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
@@ -21,7 +21,7 @@ Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-2024) and lice
21
21
  License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
22
22
  '''
23
23
  # make sure int/int division yields float quotient
24
- from __future__ import division as _; del _ # PYCHOK semicolon
24
+ from __future__ import division as _; del _ # noqa: E702 ;
25
25
 
26
26
  from pygeodesy.basics import _copysign, itemsorted, unsigned0, _xinstanceof
27
27
  from pygeodesy.constants import EPS, EPS0, EPS1, INT0, NAN, _over, \
@@ -44,7 +44,7 @@ from pygeodesy.namedTuples import Distance2Tuple, LatLon2Tuple
44
44
  from pygeodesy.props import deprecated_method, Property, Property_RO, \
45
45
  property_RO, _update_all
46
46
  from pygeodesy.streprs import Fmt, pairs
47
- from pygeodesy.units import Float_, Lat, Lon, Meter, Radius_, Int # PYCHOK shared
47
+ from pygeodesy.units import Float_, Lat, Lon, Meter, Radius_
48
48
  from pygeodesy.utily import acos1, _azireversed, _loneg, sincos2d, sincos2d_, \
49
49
  _unrollon, _Wrap
50
50
  from pygeodesy.vector3d import _intersect3d3, Vector3d # in .Intersection below
@@ -52,7 +52,7 @@ from pygeodesy.vector3d import _intersect3d3, Vector3d # in .Intersection below
52
52
  from math import cos, fabs
53
53
 
54
54
  __all__ = ()
55
- __version__ = '25.04.14'
55
+ __version__ = '25.05.12'
56
56
 
57
57
  _anti_ = _Dash('anti')
58
58
  _rls = [] # instances of C{RbumbLine...} to be updated
pygeodesy/rhumb/ekx.py CHANGED
@@ -20,7 +20,7 @@ Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2014-2024) and lice
20
20
  License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
21
21
  '''
22
22
  # make sure int/int division yields float quotient
23
- from __future__ import division as _; del _ # PYCHOK semicolon
23
+ from __future__ import division as _; del _ # noqa: E702 ;
24
24
 
25
25
  from pygeodesy.basics import copysign0, neg
26
26
  from pygeodesy.constants import PI_2, _0_0s, _0_0, _0_5, _1_0, \
@@ -31,8 +31,7 @@ from pygeodesy.errors import RhumbError, _xkwds_pop2, _Xorder
31
31
  from pygeodesy.fmath import hypot, hypot1
32
32
  # from pygeodesy.fsums import fsum1f_ # _MODS
33
33
  # from pygeodesy.karney import Caps # from .rhumb.bases
34
- from pygeodesy.ktm import KTransverseMercator, _Xs, \
35
- _AlpCoeffs, _BetCoeffs # PYCHOK used!
34
+ from pygeodesy.ktm import _Xs, _AlpCoeffs, _BetCoeffs # PYCHOK used!
36
35
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
37
36
  from pygeodesy.props import deprecated_method, Property, Property_RO, \
38
37
  property_RO
@@ -43,7 +42,7 @@ from pygeodesy.utily import atan1, sincos2_
43
42
  from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan # as _tan
44
43
 
45
44
  __all__ = _ALL_LAZY.rhumb_ekx
46
- __version__ = '25.04.12'
45
+ __version__ = '25.05.12'
47
46
 
48
47
 
49
48
  class Rhumb(RhumbBase):
pygeodesy/rhumb/solve.py CHANGED
@@ -9,7 +9,7 @@ as an (exact) rhumb or rhumb line from I{either GeographicLib 2.0 or 2.2+}.
9
9
  path of the C{RhumbSolve} executable.
10
10
  '''
11
11
  from pygeodesy.basics import _xinstanceof
12
- from pygeodesy.constants import _0_0, _180_0, _N_180_0, _over, _90_0 # PYCHOK used!
12
+ from pygeodesy.constants import _180_0, _N_180_0, _over, _0_0 # PYCHOK used!
13
13
  from pygeodesy.errors import RhumbError # PYCHOK used!
14
14
  from pygeodesy.interns import NN, _a12_, _azi12_, _DMAIN_, _lat2_, _lon2_, _s12_, \
15
15
  _S12_, _UNDER_
@@ -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__ = '25.04.12'
24
+ __version__ = '25.05.07'
25
25
 
26
26
 
27
27
  class _RhumbSolveBase(_SolveGDictBase):
pygeodesy/simplify.py CHANGED
@@ -65,7 +65,7 @@ See:
65
65
  - U{https://PyPI.org/project/simplification}
66
66
  '''
67
67
  # make sure int/int division yields float quotient, see .basics
68
- from __future__ import division as _; del _ # PYCHOK semicolon
68
+ from __future__ import division as _; del _ # noqa: E702 ;
69
69
 
70
70
  # from pygeodesy.basics import len2 # from .fmath
71
71
  from pygeodesy.constants import EPS, R_M, _1_0
@@ -80,7 +80,7 @@ from pygeodesy.units import _ALL_LAZY, _1mm, Radius_
80
80
  from math import degrees, fabs, radians
81
81
 
82
82
  __all__ = _ALL_LAZY.simplify
83
- __version__ = '24.12.02'
83
+ __version__ = '25.05.12'
84
84
 
85
85
 
86
86
  # try:
pygeodesy/solveBase.py CHANGED
@@ -20,10 +20,10 @@ from pygeodesy.named import callername, _name2__, notOverloaded
20
20
  from pygeodesy.props import Property, Property_RO, property_RO, _update_all
21
21
  from pygeodesy.streprs import Fmt, fstr, fstrzs, pairs, strs
22
22
  from pygeodesy.units import Precision_
23
- from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
23
+ from pygeodesy.utily import unroll180
24
24
 
25
25
  __all__ = _ALL_LAZY.solveBase
26
- __version__ = '25.04.14'
26
+ __version__ = '25.05.12'
27
27
 
28
28
  _ERROR_ = 'ERROR'
29
29
 
@@ -10,10 +10,10 @@ and published under the same MIT Licence**, see
10
10
  U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}.
11
11
  '''
12
12
  # make sure int/int division yields float quotient, see .basics
13
- from __future__ import division as _; del _ # PYCHOK semicolon
13
+ from __future__ import division as _; del _ # noqa: E702 ;
14
14
 
15
15
  from pygeodesy.basics import _copysign, isbool, _isin, isinstanceof, map1
16
- from pygeodesy.cartesianBase import CartesianBase, Bearing2Tuple
16
+ from pygeodesy.cartesianBase import CartesianBase
17
17
  from pygeodesy.constants import EPS, EPS0, PI, PI2, PI_2, R_M, \
18
18
  _0_0, _0_5, _1_0, _180_0, _360_0, \
19
19
  _over, isnear0, isnon0
@@ -24,9 +24,9 @@ from pygeodesy.fmath import favg, fdot, hypot, sqrt_a
24
24
  from pygeodesy.interns import _COMMA_, _concentric_, _datum_, _distant_, \
25
25
  _exceed_PI_radians_, _name_, _near_, \
26
26
  _radius_, _too_
27
- from pygeodesy.latlonBase import LatLonBase, _trilaterate5 # PYCHOK passed
27
+ from pygeodesy.latlonBase import LatLonBase
28
28
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
29
- # from pygeodesy.namedTuples import Bearing2Tuple # from .cartesianBase
29
+ # from pygeodesy.namedTuples import Bearing2Tuple # _MODS
30
30
  from pygeodesy.nvectorBase import NvectorBase, Fmt
31
31
  from pygeodesy.props import deprecated_method, property_doc_, property_RO, \
32
32
  _update_all
@@ -40,7 +40,7 @@ from pygeodesy.utily import acos1, asin1, atan2b, atan2d, degrees90, \
40
40
  from math import cos, fabs, log, sin, sqrt
41
41
 
42
42
  __all__ = _ALL_LAZY.sphericalBase
43
- __version__ = '25.04.14'
43
+ __version__ = '25.05.26'
44
44
 
45
45
 
46
46
  class CartesianSphericalBase(CartesianBase):
@@ -157,7 +157,7 @@ class LatLonSphericalBase(LatLonBase):
157
157
  # .initialBearingTo is inside .-Nvector and .-Trigonometry
158
158
  i = self.initialBearingTo(other, wrap=wrap, raiser=raiser) # PYCHOK .initialBearingTo
159
159
  f = self.finalBearingTo( other, wrap=wrap, raiser=raiser)
160
- return Bearing2Tuple(i, f, name=self.name)
160
+ return _MODS.namedTuples.Bearing2Tuple(i, f, name=self.name)
161
161
 
162
162
  @property_doc_(''' this point's datum (L{Datum}).''')
163
163
  def datum(self):
@@ -592,7 +592,7 @@ def _intersecant2(c, r, p, b, radius=R_M, exact=False, height=None, wrap=False):
592
592
  p = _unrollon(c, p, wrap=wrap)
593
593
  nonexact = exact is None
594
594
 
595
- if not isinstanceof(r, c.__class__, p.__class__):
595
+ if not isinstanceof(r, type(c), type(p)):
596
596
  r = Radius_(circle=r)
597
597
  elif nonexact:
598
598
  r = c.distanceTo(r, radius=radius, wrap=wrap)
@@ -601,7 +601,7 @@ def _intersecant2(c, r, p, b, radius=R_M, exact=False, height=None, wrap=False):
601
601
  else:
602
602
  raise _ValueError(exact=exact)
603
603
 
604
- if not isinstanceof(b, c.__class__, p.__class__):
604
+ if not isinstanceof(b, type(c), type(p)):
605
605
  b = Bearing(b)
606
606
  elif nonexact:
607
607
  b = p.initialBearingTo(b, wrap=wrap)