pygeodesy 25.4.8__py2.py3-none-any.whl → 25.4.25__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 (96) hide show
  1. pygeodesy/__init__.py +30 -27
  2. pygeodesy/__main__.py +3 -3
  3. pygeodesy/albers.py +29 -36
  4. pygeodesy/auxilats/_CX_4.py +2 -2
  5. pygeodesy/auxilats/_CX_6.py +2 -2
  6. pygeodesy/auxilats/_CX_8.py +2 -2
  7. pygeodesy/auxilats/_CX_Rs.py +9 -9
  8. pygeodesy/auxilats/__init__.py +3 -3
  9. pygeodesy/auxilats/__main__.py +8 -6
  10. pygeodesy/auxilats/auxAngle.py +2 -2
  11. pygeodesy/auxilats/auxLat.py +5 -5
  12. pygeodesy/auxilats/auxily.py +5 -3
  13. pygeodesy/azimuthal.py +7 -6
  14. pygeodesy/basics.py +31 -17
  15. pygeodesy/booleans.py +12 -10
  16. pygeodesy/cartesianBase.py +21 -20
  17. pygeodesy/clipy.py +11 -10
  18. pygeodesy/constants.py +11 -10
  19. pygeodesy/css.py +14 -11
  20. pygeodesy/datums.py +8 -8
  21. pygeodesy/deprecated/bases.py +2 -2
  22. pygeodesy/deprecated/classes.py +2 -2
  23. pygeodesy/deprecated/consterns.py +4 -4
  24. pygeodesy/dms.py +8 -8
  25. pygeodesy/ecef.py +10 -7
  26. pygeodesy/elevations.py +9 -8
  27. pygeodesy/ellipsoidalBase.py +19 -8
  28. pygeodesy/ellipsoidalBaseDI.py +17 -15
  29. pygeodesy/ellipsoidalNvector.py +6 -3
  30. pygeodesy/ellipsoidalVincenty.py +4 -1
  31. pygeodesy/ellipsoids.py +167 -138
  32. pygeodesy/elliptic.py +9 -9
  33. pygeodesy/errors.py +44 -43
  34. pygeodesy/etm.py +7 -7
  35. pygeodesy/fmath.py +10 -9
  36. pygeodesy/formy.py +11 -12
  37. pygeodesy/frechet.py +216 -109
  38. pygeodesy/fstats.py +5 -4
  39. pygeodesy/fsums.py +78 -77
  40. pygeodesy/gars.py +4 -3
  41. pygeodesy/geodesici.py +15 -14
  42. pygeodesy/geodesicw.py +34 -32
  43. pygeodesy/geodesicx/__init__.py +1 -1
  44. pygeodesy/geodesicx/__main__.py +11 -9
  45. pygeodesy/geodesicx/gx.py +30 -33
  46. pygeodesy/geodesicx/gxarea.py +2 -2
  47. pygeodesy/geodesicx/gxline.py +5 -5
  48. pygeodesy/geodsolve.py +18 -17
  49. pygeodesy/geohash.py +5 -5
  50. pygeodesy/geoids.py +34 -31
  51. pygeodesy/hausdorff.py +17 -13
  52. pygeodesy/heights.py +2 -4
  53. pygeodesy/internals.py +28 -44
  54. pygeodesy/interns.py +10 -7
  55. pygeodesy/iters.py +8 -8
  56. pygeodesy/karney.py +68 -62
  57. pygeodesy/ktm.py +5 -5
  58. pygeodesy/latlonBase.py +14 -18
  59. pygeodesy/lazily.py +65 -63
  60. pygeodesy/lcc.py +11 -9
  61. pygeodesy/ltp.py +8 -7
  62. pygeodesy/ltpTuples.py +2 -2
  63. pygeodesy/mgrs.py +7 -6
  64. pygeodesy/named.py +47 -31
  65. pygeodesy/nvectorBase.py +7 -7
  66. pygeodesy/osgr.py +9 -8
  67. pygeodesy/points.py +12 -10
  68. pygeodesy/props.py +25 -25
  69. pygeodesy/resections.py +11 -10
  70. pygeodesy/rhumb/__init__.py +1 -1
  71. pygeodesy/rhumb/aux_.py +7 -7
  72. pygeodesy/rhumb/bases.py +22 -20
  73. pygeodesy/rhumb/ekx.py +6 -6
  74. pygeodesy/rhumb/solve.py +15 -15
  75. pygeodesy/solveBase.py +3 -3
  76. pygeodesy/sphericalBase.py +6 -6
  77. pygeodesy/sphericalNvector.py +6 -5
  78. pygeodesy/sphericalTrigonometry.py +8 -7
  79. pygeodesy/streprs.py +14 -14
  80. pygeodesy/trf.py +14 -12
  81. pygeodesy/triaxials.py +29 -26
  82. pygeodesy/units.py +5 -4
  83. pygeodesy/unitsBase.py +5 -4
  84. pygeodesy/ups.py +3 -3
  85. pygeodesy/utily.py +4 -4
  86. pygeodesy/utmups.py +4 -4
  87. pygeodesy/utmupsBase.py +88 -18
  88. pygeodesy/vector2d.py +18 -11
  89. pygeodesy/vector3d.py +7 -6
  90. pygeodesy/webmercator.py +6 -5
  91. pygeodesy/wgrs.py +6 -5
  92. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +27 -23
  93. pygeodesy-25.4.25.dist-info/RECORD +118 -0
  94. pygeodesy-25.4.8.dist-info/RECORD +0 -118
  95. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
  96. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/resections.py CHANGED
@@ -12,7 +12,7 @@ L{triAngle}, L{triAngle5}, L{triSide}, L{triSide2} and L{triSide4}.
12
12
  # make sure int/int division yields float quotient
13
13
  from __future__ import division as _; del _ # PYCHOK semicolon
14
14
 
15
- from pygeodesy.basics import map1, map2, _zip, _ALL_LAZY
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, \
17
17
  _0_0, _0_5, _1_0, _N_1_0, _2_0, _N_2_0, _4_0, \
18
18
  _16_0, _180_0, _360_0, isnear0, _over, _umod_360
@@ -20,6 +20,7 @@ from pygeodesy.errors import _and, _or, TriangleError, _ValueError, _xcallable,
20
20
  _xkwds, _xkwds_pop2
21
21
  from pygeodesy.fmath import favg, Fdot, fidw, fmean, hypot, hypot2_
22
22
  from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1, fsum1f_
23
+ # from pygeodesy.internals import typename # from .basics
23
24
  from pygeodesy.interns import _a_, _A_, _area_, _b_, _B_, _c_, _C_, _coincident_, \
24
25
  _colinear_, _d_, _invalid_, _negative_, _not_, \
25
26
  _rIn_, _SPACE_
@@ -34,7 +35,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d
34
35
  from math import cos, degrees, fabs, radians, sin, sqrt
35
36
 
36
37
  __all__ = _ALL_LAZY.resections
37
- __version__ = '24.11.27'
38
+ __version__ = '25.04.14'
38
39
 
39
40
  _concyclic_ = 'concyclic'
40
41
  _PA_ = 'PA'
@@ -204,7 +205,7 @@ def _Clas(which, point, Clas_and_kwds, *args):
204
205
  '''(INTERNAL) Return a C{B{Clas}=point.classof} survey point.
205
206
  '''
206
207
  Clas, kwds = _xkwds_pop2(Clas_and_kwds, Clas=point.classof)
207
- return Clas(*args, **_xkwds(kwds, name=which.__name__))
208
+ return Clas(*args, **_xkwds(kwds, name=typename(which)))
208
209
 
209
210
 
210
211
  def collins5(pointA, pointB, pointC, alpha, beta, useZ=False, **Clas_and_kwds):
@@ -286,7 +287,7 @@ def collins5(pointA, pointB, pointC, alpha, beta, useZ=False, **Clas_and_kwds):
286
287
  P = _Clas(collins5, pointA, Clas_and_kwds, *P)
287
288
  H = _Clas(collins5, pointA, Clas_and_kwds, *H)
288
289
  a = B.minus(C).length
289
- return Collins5Tuple(P, H, a, b, c, name=collins5.__name__)
290
+ return Collins5Tuple(P, H, a, b, c, name=typename(collins5))
290
291
 
291
292
  except (TypeError, ValueError) as x:
292
293
  raise ResectionError(pointA=pointA, pointB=pointB, pointC=pointC,
@@ -576,7 +577,7 @@ def snellius3(a, b, degC, alpha, beta):
576
577
 
577
578
  pa = _triSide(b, pc, fsumf_(PI, -ra, -pa))
578
579
  pb = _triSide(a, pc, fsumf_(PI, -rb, -pb))
579
- return Survey3Tuple(pa, pb, pc, name=snellius3.__name__)
580
+ return Survey3Tuple(pa, pb, pc, name=typename(snellius3))
580
581
 
581
582
  except (TypeError, ValueError) as x:
582
583
  raise TriangleError(a=a, b=b, degC=degC, alpha=alpha, beta=beta, cause=x)
@@ -672,7 +673,7 @@ def tienstra7(pointA, pointB, pointC, alpha, beta=None, gamma=None,
672
673
  z = _zidw(x, y, useZ, A, B, C)
673
674
 
674
675
  P = _Clas(tienstra7, pointA, Clas_and_kwds, x, y, z)
675
- return Tienstra7Tuple(P, dA, dB, dC, a, b, c, name=tienstra7.__name__)
676
+ return Tienstra7Tuple(P, dA, dB, dC, a, b, c, name=typename(tienstra7))
676
677
 
677
678
  except (TypeError, ValueError) as x:
678
679
  raise ResectionError(pointA=pointA, pointB=pointB, pointC=pointC,
@@ -771,7 +772,7 @@ def triAngle5(a, b, c):
771
772
  rB, rC = rC, rB
772
773
  if ab:
773
774
  rA, rB = rB, rA
774
- return TriAngle5Tuple(rA, rB, rC, r, s, name=triAngle5.__name__)
775
+ return TriAngle5Tuple(rA, rB, rC, r, s, name=typename(triAngle5))
775
776
 
776
777
  except (TypeError, ValueError) as x:
777
778
  raise TriangleError(a=a, b=b, c=c, cause=x)
@@ -892,7 +893,7 @@ def _triSide2(b, c, radB):
892
893
  else:
893
894
  rA = fsumf_(PI, -rB, -asin1(c * sB / b))
894
895
  a = sin(rA) * b / sB
895
- return TriSide2Tuple(a, rA, name=triSide2.__name__)
896
+ return TriSide2Tuple(a, rA, name=typename(triSide2))
896
897
 
897
898
 
898
899
  def triSide4(radA, radB, c):
@@ -927,7 +928,7 @@ def triSide4(radA, radB, c):
927
928
  raise ValueError(_invalid_)
928
929
  sc = c / sc
929
930
  return TriSide4Tuple((sa * sc), (sb * sc), rC, (sa * sb * sc),
930
- name=triSide4.__name__)
931
+ name=typename(triSide4))
931
932
 
932
933
  except (TypeError, ValueError) as x:
933
934
  raise TriangleError(radA=radA, radB=radB, c=c, cause=x)
@@ -1002,7 +1003,7 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
1002
1003
  pb = _vpa(r3, q1, q3, s1, s3)
1003
1004
  pc = favg(_triSide2(b, pa, ra).a,
1004
1005
  _triSide2(a, pb, rb).a)
1005
- return Survey3Tuple(pa, pb, pc, name=wildberger3.__name__)
1006
+ return Survey3Tuple(pa, pb, pc, name=typename(wildberger3))
1006
1007
 
1007
1008
  except (TypeError, ValueError) as x:
1008
1009
  raise TriangleError(a=a, b=b, c=c, alpha=alpha, beta=beta, R3=R3, cause=x)
@@ -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.01.15'
12
+ __version__ = '25.04.14'
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.01.15'
51
+ __version__ = '25.04.12'
52
52
 
53
53
  # DIGITS = (sizeof(real) * 8) bits
54
54
  # = (ctypes.sizeof(ctypes.c_double(1.0)) * 8) bits
@@ -216,11 +216,11 @@ class RhumbLineAux(RhumbLineBase):
216
216
  @kwarg lat1: Latitude of the start point (C{degrees90}).
217
217
  @kwarg lon1: Longitude of the start point (C{degrees180}).
218
218
  @kwarg azi12: Azimuth of this rhumb line (compass C{degrees}).
219
- @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and
220
- C{B{caps}=0}, a bit-or'ed combination of L{Caps}
221
- values specifying the required capabilities. Include
222
- C{Caps.LINE_OFF} if updates to the B{C{rhumb}} should
223
- I{not} be reflected in this rhumb line.
219
+ @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and C{B{caps}=0},
220
+ a bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>} values
221
+ specifying the required capabilities. Include C{Caps.LINE_OFF}
222
+ if updates to the B{C{rhumb}} should I{not be reflected} in this
223
+ rhumb line.
224
224
  '''
225
225
  RhumbLineBase.__init__(self, rhumb, lat1, lon1, azi12, **caps_name)
226
226
 
@@ -296,7 +296,7 @@ def _RAintegrate(auxD):
296
296
  def _RAseries(auxD):
297
297
  # Series expansions in n for Fourier coeffients of the integral
298
298
  # @see: U{"Series expansions for computing rhumb areas"
299
- # <https:#DOI.org/10.5281/zenodo.7685484>}.
299
+ # <https://DOI.org/10.5281/zenodo.7685484>}.
300
300
  d = n = auxD._n
301
301
  i = 0
302
302
  aL = auxD.ALorder
pygeodesy/rhumb/bases.py CHANGED
@@ -33,9 +33,9 @@ from pygeodesy.errors import IntersectionError, RhumbError, _xdatum, \
33
33
  from pygeodesy.fmath import euclid, favg, sqrt_a, Fsum
34
34
  # from pygeodesy.formy import opposing # _MODS
35
35
  # from pygeodesy.fsums import Fsum # from .fmath
36
- from pygeodesy.internals import _DUNDER_nameof, _under
36
+ from pygeodesy.internals import typename, _under
37
37
  from pygeodesy.interns import NN, _coincident_, _COMMASPACE_, _Dash, \
38
- _parallel_, _too_
38
+ _DMAIN_, _parallel_, _too_
39
39
  from pygeodesy.karney import _atan2d, Caps, _CapsBase, _diff182, _fix90, \
40
40
  _norm180, GDict
41
41
  # from pygeodesy.ktm import KTransverseMercator, _AlpCoeffs # _MODS
@@ -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__ = '24.10.14'
55
+ __version__ = '25.04.14'
56
56
 
57
57
  _anti_ = _Dash('anti')
58
58
  _rls = [] # instances of C{RbumbLine...} to be updated
@@ -231,9 +231,10 @@ class RhumbBase(_CapsBase):
231
231
  @arg azi12: Azimuth of the rhumb line (compass C{degrees}).
232
232
  @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and
233
233
  C{B{caps}=Caps.STANDARD}, a bit-or'ed combination of
234
- L{Caps} values specifying the required capabilities.
235
- Include C{Caps.LINE_OFF} if updates to the B{C{rhumb}}
236
- should I{not} be reflected in this rhumb line.
234
+ L{Caps<pygeodesy.karney.Caps>} values specifying the
235
+ required capabilities. Include C{Caps.LINE_OFF} if
236
+ updates to the B{C{rhumb}} should I{not be reflected}
237
+ in this rhumb line.
237
238
 
238
239
  @return: A C{RhumbLine...} instance and invoke its method
239
240
  C{.Position} to compute each point.
@@ -397,9 +398,10 @@ class RhumbBase(_CapsBase):
397
398
  @arg lon2: Longitude of the second point (C{degrees180}).
398
399
  @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and
399
400
  C{B{caps}=Caps.STANDARD}, a bit-or'ed combination of
400
- L{Caps} values specifying the required capabilities.
401
- Include C{Caps.LINE_OFF} if updates to the B{C{rhumb}}
402
- should I{not} be reflected in this rhumb line.
401
+ L{Caps<pygeodesy.karney.Caps>} values specifying the
402
+ required capabilities. Include C{Caps.LINE_OFF} if
403
+ updates to the B{C{rhumb}} should I{not be reflected}
404
+ in this rhumb line.
403
405
 
404
406
  @return: A C{RhumbLine...} instance and invoke its method
405
407
  C{ArcPosition} or C{Position} to compute points.
@@ -517,8 +519,8 @@ class RhumbLineBase(_CapsBase):
517
519
 
518
520
  @arg a12: The angle along this rhumb line from its origin to the
519
521
  point (C{degrees}), can be negative.
520
- @kwarg outmask: Bit-or'ed combination of L{Caps} values specifying
521
- the quantities to be returned.
522
+ @kwarg outmask: Bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>}
523
+ values specifying the quantities to be returned.
522
524
 
523
525
  @return: L{GDict} with 4 to 8 items C{azi12, a12, s12, S12, lat2,
524
526
  lon2, lat1, lon1} with latitude C{lat2} and longitude
@@ -634,7 +636,7 @@ class RhumbLineBase(_CapsBase):
634
636
  t = dict(lat3=q.lat2, lon3=q.lon2, azi03=q.azi02, a03=q.a02, s03=a)
635
637
  if a < r:
636
638
  t.update(iteration=q.iteration, lat0=q.lat1, lon0=q.lon1, # or lat0, lon0
637
- name=_DUNDER_nameof(self.Intersecant2, self.name))
639
+ name=typename(self.Intersecant2, self.name))
638
640
  if fabs(a) < EPS0: # coincident centers
639
641
  d, h = _0_0, r
640
642
  else:
@@ -660,7 +662,7 @@ class RhumbLineBase(_CapsBase):
660
662
  def intersection2(self, other, **tol_eps): # PYCHOK no cover
661
663
  '''DEPRECATED on 23.10.10, use method L{Intersection}.'''
662
664
  p = self.Intersection(other, **tol_eps)
663
- r = LatLon2Tuple(p.lat2, p.lon2, name=self.intersection2.__name__)
665
+ r = LatLon2Tuple(p.lat2, p.lon2, name=typename(self.intersection2))
664
666
  r._iteration = p.iteration
665
667
  return r
666
668
 
@@ -701,7 +703,7 @@ class RhumbLineBase(_CapsBase):
701
703
  _s_3d, s_az = self._xTM3d, self.azi12
702
704
  _o_3d, o_az = other._xTM3d, other.azi12
703
705
  p = _MODS.formy.opposing(s_az, o_az, margin=tol)
704
- if p is not None: # == p in (True, False)
706
+ if p is not None: # == isbool(p)
705
707
  raise ValueError(_anti_(_parallel_) if p else _parallel_)
706
708
  _diff = euclid # approximate length
707
709
  _i3d3 = _intersect3d3 # NOT .vector3d.intersection3d3
@@ -723,7 +725,7 @@ class RhumbLineBase(_CapsBase):
723
725
 
724
726
  P = GDict(lat1=self.lat1, lat2=p.lat, lat0=other.lat1,
725
727
  lon1=self.lon1, lon2=p.lon, lon0=other.lon1,
726
- name=_DUNDER_nameof(self.Intersection, self.name))
728
+ name=typename(self.Intersection, self.name))
727
729
  r = self.Inverse(p.lat, p.lon, outmask=Caps.DISTANCE)
728
730
  t = other.Inverse(p.lat, p.lon, outmask=Caps.DISTANCE)
729
731
  P.set_(azi12= self.azi12, a12=r.a12, s12=r.s12,
@@ -805,7 +807,7 @@ class RhumbLineBase(_CapsBase):
805
807
  '''DEPRECATED on 23.10.10, use method L{PlumbTo}.'''
806
808
  P = self.PlumbTo(lat0, lon0, **exact_eps_est_tol)
807
809
  r = _MODS.deprecated.classes.NearestOn4Tuple(P.lat2, P.lon2, P.s12, P.azi02,
808
- name=self.nearestOn4.__name__)
810
+ name=typename(self.nearestOn4))
809
811
  r._iteration = P.iteration
810
812
  return r
811
813
 
@@ -897,7 +899,7 @@ class RhumbLineBase(_CapsBase):
897
899
  break
898
900
  P.set_(azi0=r.azi1, a02=r.a12, s02=r.s12, # azi2=r.azi2,
899
901
  lat0=lat0, lon0=lon0, iteration=i, at=r.azi2 - self.azi12,
900
- name=_DUNDER_nameof(self.PlumbTo, self.name))
902
+ name=typename(self.PlumbTo, self.name))
901
903
  except Exception as x: # Fsum(NAN) Value-, ZeroDivisionError
902
904
  raise IntersectionError(lat0=lat0, lon0=lon0, tol=tol, exact=exact,
903
905
  eps=eps, est=est, iteration=i, cause=x)
@@ -909,8 +911,8 @@ class RhumbLineBase(_CapsBase):
909
911
 
910
912
  @arg s12: The distance along this rhumb line from its origin to the point
911
913
  (C{meters}), can be negative.
912
- @kwarg outmask: Bit-or'ed combination of L{Caps} values specifying the
913
- quantities to be returned.
914
+ @kwarg outmask: Bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>}
915
+ values specifying the quantities to be returned.
914
916
 
915
917
  @return: L{GDict} with 4 to 8 items C{azi12, a12, s12, S12, lat2, lat1,
916
918
  lon2, lon1} with latitude C{lat2} and longitude C{lon2} of the
@@ -1046,7 +1048,7 @@ class _PseudoRhumbLine(RhumbLineBase):
1046
1048
 
1047
1049
  __all__ += _ALL_DOCS(RhumbBase, RhumbLineBase)
1048
1050
 
1049
- if __name__ == '__main__':
1051
+ if __name__ == _DMAIN_:
1050
1052
 
1051
1053
  from pygeodesy import printf, Rhumb as Rh, RhumbAux as Ah
1052
1054
  from pygeodesy.basics import _zip
pygeodesy/rhumb/ekx.py CHANGED
@@ -43,7 +43,7 @@ from pygeodesy.utily import atan1, sincos2_
43
43
  from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan # as _tan
44
44
 
45
45
  __all__ = _ALL_LAZY.rhumb_ekx
46
- __version__ = '24.11.26'
46
+ __version__ = '25.04.12'
47
47
 
48
48
 
49
49
  class Rhumb(RhumbBase):
@@ -263,11 +263,11 @@ class RhumbLine(RhumbLineBase):
263
263
  @kwarg lat1: Latitude of the start point (C{degrees90}).
264
264
  @kwarg lon1: Longitude of the start point (C{degrees180}).
265
265
  @kwarg azi12: Azimuth of this rhumb line (compass C{degrees}).
266
- @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and
267
- C{B{caps}=0}, a bit-or'ed combination of L{Caps}
268
- values specifying the required capabilities. Include
269
- C{Caps.LINE_OFF} if updates to the B{C{rhumb}} should
270
- I{not} be reflected in this rhumb line.
266
+ @kwarg caps_name: Optional keyword arguments C{B{name}=NN} and C{B{caps}=0},
267
+ a bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>} values
268
+ specifying the required capabilities. Include C{Caps.LINE_OFF}
269
+ if updates to the B{C{rhumb}} should I{not be reflected} in this
270
+ rhumb line.
271
271
  '''
272
272
  RhumbLineBase.__init__(self, rhumb, lat1, lon1, azi12, **caps_name)
273
273
 
pygeodesy/rhumb/solve.py CHANGED
@@ -11,7 +11,8 @@ as an (exact) rhumb or rhumb line from I{either GeographicLib 2.0 or 2.2+}.
11
11
  from pygeodesy.basics import _xinstanceof
12
12
  from pygeodesy.constants import _0_0, _180_0, _N_180_0, _over, _90_0 # PYCHOK used!
13
13
  from pygeodesy.errors import RhumbError # PYCHOK used!
14
- from pygeodesy.interns import NN, _a12_, _azi12_, _lat2_, _lon2_, _s12_, _S12_, _UNDER_
14
+ from pygeodesy.interns import NN, _a12_, _azi12_, _DMAIN_, _lat2_, _lon2_, _s12_, \
15
+ _S12_, _UNDER_
15
16
  from pygeodesy.karney import Caps, GDict, _norm180, Rhumb8Tuple, _sincos2d, _Xables
16
17
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
17
18
  from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
@@ -20,7 +21,7 @@ from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
20
21
  from pygeodesy.utily import _unrollon, _Wrap, wrap360
21
22
 
22
23
  __all__ = _ALL_LAZY.rhumb_solve
23
- __version__ = '24.11.07'
24
+ __version__ = '25.04.12'
24
25
 
25
26
 
26
27
  class _RhumbSolveBase(_SolveGDictBase):
@@ -29,7 +30,7 @@ class _RhumbSolveBase(_SolveGDictBase):
29
30
  _Error = RhumbError
30
31
  _Names_Direct = _lat2_, _lon2_, _S12_
31
32
  _Names_Inverse = _azi12_, _s12_, _S12_
32
- _Xable_name = _Xables.RhumbSolve.__name__
33
+ _Xable_name = _Xables.RhumbSolve.__name__ # typename
33
34
  _Xable_path = _Xables.RhumbSolve()
34
35
 
35
36
  @Property_RO
@@ -146,9 +147,9 @@ class RhumbSolve(_RhumbSolveBase):
146
147
  @arg lat1: Latitude of the first point (C{degrees}).
147
148
  @arg lon1: Longitude of the first point (C{degrees}).
148
149
  @arg azi1: Azimuth at the first point (compass C{degrees}).
149
- @kwarg caps: Bit-or'ed combination of L{Caps} values specifying
150
- the capabilities the L{RhumbLineSolve} instance
151
- should possess, always C{Caps.ALL}.
150
+ @kwarg caps: Bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>}
151
+ values specifying the capabilities the L{RhumbLineSolve}
152
+ instance should possess, always C{Caps.ALL}.
152
153
  @kwarg name: Optional C{B{name}=NN} (C{str}).
153
154
 
154
155
  @return: A L{RhumbLineSolve} instance.
@@ -247,18 +248,17 @@ class RhumbLineSolve(_RhumbSolveBase, _SolveGDictLineBase):
247
248
  @arg lat1: Latitude of the first point (C{degrees90}).
248
249
  @arg lon1: Longitude of the first point (C{degrees180}).
249
250
  @arg azi12: Azimuth of the rhumb line (compass C{degrees180}).
250
- @kwarg caps: Bit-or'ed combination of L{Caps} values specifying
251
- the capabilities the L{RhumbLineSolve} instance should
252
- possess, always C{Caps.ALL}. Use C{Caps.LINE_OFF}
253
- if updates to the B{C{rhumb}} should I{not} be
254
- reflected in this L{RhumbLineSolve} instance.
251
+ @kwarg caps: Bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>}
252
+ values specifying the capabilities the L{RhumbLineSolve}
253
+ instance should possess, always C{Caps.ALL}. Include
254
+ C{Caps.LINE_OFF} if updates to the B{C{rhumb}} should
255
+ I{not be reflected} in this L{RhumbLineSolve} instance.
255
256
  @kwarg name: Optional C{B{name}=NN} (C{str}).
256
257
 
257
258
  @kwarg name: Optional name (C{str}).
258
259
 
259
- @raise RhumbError: Invalid path for C{RhumbSolve} executable or
260
- isn't the C{RhumbSolve} executable, see
261
- property C{B{rhumb}.RhumbSolve}.
260
+ @raise RhumbError: Invalid path for C{RhumbSolve} executable or isn't the
261
+ C{RhumbSolve} executable, see property C{B{rhumb}.RhumbSolve}.
262
262
 
263
263
  @raise TypeError: Invalid B{C{rhumb}}.
264
264
  '''
@@ -355,7 +355,7 @@ class RhumbSolve7Tuple(Rhumb8Tuple):
355
355
 
356
356
  __all__ += _ALL_DOCS(_RhumbSolveBase)
357
357
 
358
- if __name__ == '__main__':
358
+ if __name__ == _DMAIN_:
359
359
 
360
360
  from pygeodesy import printf
361
361
  from sys import argv
pygeodesy/solveBase.py CHANGED
@@ -4,7 +4,7 @@
4
4
  u'''(INTERNAL) Private base classes for L{pygeodesy.geodsolve} and L{pygeodesy.rhumb.solve}.
5
5
  '''
6
6
 
7
- from pygeodesy.basics import clips, map2, _zip
7
+ from pygeodesy.basics import clips, _isin, map2, _zip
8
8
  from pygeodesy.constants import DIG
9
9
  from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
10
10
  # from pygeodesy.ellipsoids import _EWGS84 # from .datums
@@ -23,7 +23,7 @@ from pygeodesy.units import Precision_
23
23
  from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
24
24
 
25
25
  __all__ = _ALL_LAZY.solveBase
26
- __version__ = '24.10.13'
26
+ __version__ = '25.04.14'
27
27
 
28
28
  _ERROR_ = 'ERROR'
29
29
 
@@ -211,7 +211,7 @@ class _SolveCapsBase(_CapsBase):
211
211
  self._print(t)
212
212
  try: # invoke and write to stdin
213
213
  r, s = _popen2(cmd, stdin)
214
- if len(r) < 6 or r[:5] in (_Error_, _ERROR_):
214
+ if len(r) < 6 or _isin(r[:5], _Error_, _ERROR_):
215
215
  raise ValueError(r)
216
216
  except (IOError, OSError, TypeError, ValueError) as x:
217
217
  raise self._Error(cmd=t or _cmd_stdin_(cmd, stdin), cause=x)
@@ -12,7 +12,7 @@ U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}.
12
12
  # make sure int/int division yields float quotient, see .basics
13
13
  from __future__ import division as _; del _ # PYCHOK semicolon
14
14
 
15
- from pygeodesy.basics import _copysign, isbool, isinstanceof, map1
15
+ from pygeodesy.basics import _copysign, isbool, _isin, isinstanceof, map1
16
16
  from pygeodesy.cartesianBase import CartesianBase, Bearing2Tuple
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, \
@@ -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__ = '24.10.19'
43
+ __version__ = '25.04.14'
44
44
 
45
45
 
46
46
  class CartesianSphericalBase(CartesianBase):
@@ -137,7 +137,7 @@ class LatLonSphericalBase(LatLonBase):
137
137
  @raise TypeError: Invalid B{C{latlonh}} or B{C{datum}} not spherical.
138
138
  '''
139
139
  LatLonBase.__init__(self, latlonh, lon=lon, height=height, wrap=wrap, **name)
140
- if datum not in (None, self.datum):
140
+ if not _isin(datum, None, self.datum):
141
141
  self.datum = datum
142
142
 
143
143
  def bearingTo2(self, other, wrap=False, raiser=False):
@@ -403,7 +403,7 @@ class LatLonSphericalBase(LatLonBase):
403
403
  r = LatLonBase.rhumbDestination(self, distance, azimuth, exact=False, # Krüger
404
404
  radius=radius, height=height, **name)
405
405
  else: # radius=None from .rhumbMidpointTo
406
- if radius in (None, self._radius):
406
+ if _isin(radius, None, self._radius):
407
407
  d, r = self.datum, radius
408
408
  else:
409
409
  d = _spherical_datum(radius, raiser=_radius_) # spherical only
@@ -557,7 +557,7 @@ class LatLonSphericalBase(LatLonBase):
557
557
  b3 = fdot(map1(log, f1, f2, f3),
558
558
  -b2, b1, b2 - b1) / f
559
559
 
560
- d = self.datum if radius in (None, self._radius) else \
560
+ d = self.datum if _isin(radius, None, self._radius) else \
561
561
  _spherical_datum(radius, name=self.name, raiser=_radius_)
562
562
  h = self._havg(other, h=height)
563
563
  r = self.classof(degrees90(a3), degrees180(b3), datum=d, height=h, name=n)
@@ -674,7 +674,7 @@ def _m2radians(distance, radius, low=EPS): # PYCHOK in .spherical*
674
674
  def _radians2m(rad, radius):
675
675
  '''(INTERNAL) Angular distance in C{radians} to distance in C{meter}.
676
676
  '''
677
- if radius is not None: # not in (None, _0_0)
677
+ if radius is not None: # not _isin(radius, None, _0_0)
678
678
  rad *= R_M if radius is R_M else Radius(radius)
679
679
  return rad
680
680
 
@@ -33,13 +33,14 @@ to a normalised version of an (ECEF) cartesian coordinate.
33
33
  # make sure int/int division yields float quosient, see .basics
34
34
  from __future__ import division as _; del _ # PYCHOK semicolon
35
35
 
36
- # from pygeodesy.basics import _xinstanceof # _MODS
36
+ from pygeodesy.basics import _isin, _xinstanceof, typename
37
37
  from pygeodesy.constants import EPS, EPS0, PI, PI2, PI_2, R_M, \
38
38
  _0_0, _0_5, _1_0
39
39
  # from pygeodesy.datums import Datums # from .sphericalBase
40
40
  from pygeodesy.errors import PointsError, VectorError, _xError, _xkwds
41
41
  from pygeodesy.fmath import fdot_, fmean, fsum
42
42
  # from pygeodesy.fsums import fsum # from .fmath
43
+ # from pygeodesy.internals import typename # from .basics
43
44
  from pygeodesy.interns import _composite_, _end_, _Nv00_, _other_, \
44
45
  _point_, _pole_
45
46
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _ALL_OTHER
@@ -61,7 +62,7 @@ from pygeodesy.utily import atan2, degrees360, sincos2, sincos2_, sincos2d, \
61
62
  # from math import fabs # from utily
62
63
 
63
64
  __all__ = _ALL_LAZY.sphericalNvector
64
- __version__ = '24.11.24'
65
+ __version__ = '25.04.14'
65
66
 
66
67
  _lines_ = 'lines'
67
68
 
@@ -605,7 +606,7 @@ class LatLon(LatLonNvectorBase, LatLonSphericalBase):
605
606
  return p2 # is point2 if not wrap
606
607
 
607
608
  p = n.toLatLon(height=height or 0, LatLon=self.classof)
608
- if height in (None, False): # interpolate height within extent
609
+ if _isin(height, None, False): # interpolate height within extent
609
610
  d = p1.distanceTo(p2)
610
611
  f = (p1.distanceTo(p) / d) if d > EPS0 else _0_5
611
612
  p.height = p1._havg(p2, f=max(_0_0, min(f, _1_0)))
@@ -1006,7 +1007,7 @@ def meanOf(points, height=None, wrap=False, **LatLon_and_kwds):
1006
1007
  except (TypeError, ValueError) as x:
1007
1008
  raise PointsError(points=points, wrap=wrap, cause=x, **LatLon_and_kwds)
1008
1009
  return n.toLatLon(**_xkwds(LatLon_and_kwds, LatLon=LatLon, height=n.h,
1009
- name=meanOf.__name__))
1010
+ name=typename(meanOf)))
1010
1011
 
1011
1012
 
1012
1013
  @deprecated_function
@@ -1050,7 +1051,7 @@ def nearestOn3(point, points, closed=False, radius=R_M, height=None, wrap=False)
1050
1051
 
1051
1052
  @raise TypeError: Some B{C{points}} or B{C{point}} not C{LatLon}.
1052
1053
  '''
1053
- _MODS.basics._xinstanceof(LatLon, point=point)
1054
+ _xinstanceof(LatLon, point=point)
1054
1055
 
1055
1056
  return point.nearestOn3(points, closed=closed, radius=radius,
1056
1057
  height=height, wrap=wrap)
@@ -16,7 +16,7 @@ U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}.
16
16
  # make sure int/int division yields float quotient, see .basics
17
17
  from __future__ import division as _; del _ # PYCHOK semicolon
18
18
 
19
- from pygeodesy.basics import copysign0, map1, signOf
19
+ from pygeodesy.basics import copysign0, _isin, map1, signOf, typename
20
20
  from pygeodesy.constants import EPS, EPS1, EPS4, PI, PI2, PI_2, PI_4, R_M, \
21
21
  isnear0, isnear1, isnon0, _0_0, _0_5, \
22
22
  _1_0, _2_0, _90_0
@@ -29,6 +29,7 @@ from pygeodesy.fsums import Fsum, fsum, fsumf_
29
29
  from pygeodesy.formy import antipode_, bearing_, _bearingTo2, excessAbc_, \
30
30
  excessGirard_, excessLHuilier_, opposing_, _radical2, \
31
31
  vincentys_
32
+ # from pygeodesy.internals import typename # from .basics
32
33
  from pygeodesy.interns import _1_, _2_, _coincident_, _composite_, _colinear_, \
33
34
  _concentric_, _convex_, _end_, _infinite_, \
34
35
  _invalid_, _line_, _near_, _null_, _parallel_, \
@@ -55,7 +56,7 @@ from pygeodesy.vector3d import sumOf, Vector3d
55
56
  from math import asin, cos, degrees, fabs, radians, sin
56
57
 
57
58
  __all__ = _ALL_LAZY.sphericalTrigonometry
58
- __version__ = '24.11.24'
59
+ __version__ = '25.04.14'
59
60
 
60
61
  _PI_EPS4 = PI - EPS4
61
62
  if _PI_EPS4 >= PI:
@@ -1147,7 +1148,7 @@ def isPoleEnclosedBy(points, wrap=False): # PYCHOK no cover
1147
1148
  def _LL3Tuple(lat, lon, height, where, LatLon, LatLon_kwds):
1148
1149
  '''(INTERNAL) Helper for L{intersection}, L{intersections2} and L{meanOf}.
1149
1150
  '''
1150
- n = where.__name__
1151
+ n = typename(where)
1151
1152
  if LatLon is None:
1152
1153
  r = LatLon3Tuple(lat, lon, height, name=n)
1153
1154
  else:
@@ -1250,7 +1251,7 @@ def nearestOn3(point, points, closed=False, radius=R_M, wrap=False, adjust=True,
1250
1251
  adjust=adjust, limit=limit)
1251
1252
  d = degrees2m(t.distance, radius=radius)
1252
1253
  h = t.height
1253
- n = nearestOn3.__name__
1254
+ n = typename(nearestOn3)
1254
1255
 
1255
1256
  LL, kwds = _xkwds_pop2(LatLon_and_kwds, LatLon=LatLon)
1256
1257
  r = LatLon3Tuple(t.lat, t.lon, h, name=n) if LL is None else \
@@ -1378,8 +1379,8 @@ def triangle8_(phiA, lamA, phiB, lamB, phiC, lamC, excess=excessAbc_,
1378
1379
  C, _ = _A_r(c, *r)
1379
1380
 
1380
1381
  D = fsumf_(PI2, -a, -b, -c) # deficit aka defect
1381
- E = excessGirard_(A, B, C) if excess in (excessGirard_, True) else (
1382
- excessLHuilier_(a, b, c) if excess in (excessLHuilier_, False) else
1382
+ E = excessGirard_(A, B, C) if _isin(excess, excessGirard_, True) else (
1383
+ excessLHuilier_(a, b, c) if _isin(excess, excessLHuilier_, False) else
1383
1384
  excessAbc_(*max((A, b, c), (B, c, a), (C, a, b))))
1384
1385
 
1385
1386
  return Triangle8Tuple(A, a, B, b, C, c, D, E)
@@ -1388,7 +1389,7 @@ def triangle8_(phiA, lamA, phiB, lamB, phiC, lamC, excess=excessAbc_,
1388
1389
  def _t7Tuple(t, radius):
1389
1390
  '''(INTERNAL) Convert a L{Triangle8Tuple} to L{Triangle7Tuple}.
1390
1391
  '''
1391
- if radius: # not in (None, _0_0)
1392
+ if radius: # not _isin(radius, None, _0_0)
1392
1393
  r = radius if _isRadius(radius) else \
1393
1394
  _ellipsoidal_datum(radius).ellipsoid.Rmean
1394
1395
  A, B, C = map1(degrees, t.A, t.B, t.C)
pygeodesy/streprs.py CHANGED
@@ -5,11 +5,11 @@ u'''Floating point and other formatting utilities.
5
5
  '''
6
6
 
7
7
  from pygeodesy.basics import isint, islistuple, isscalar, isstr, itemsorted, \
8
- _zip, _0_0
8
+ _zip, _0_0, typename
9
9
  # from pygeodesy.constants import _0_0
10
10
  from pygeodesy.errors import _or, _IsnotError, _TypeError, _ValueError, \
11
11
  _xkwds_get, _xkwds_item2
12
- from pygeodesy.internals import _DUNDER_nameof
12
+ # from pygeodesy.internals import typename # from .basics
13
13
  from pygeodesy.interns import NN, _0_, _0to9_, MISSING, _BAR_, _COMMASPACE_, \
14
14
  _DOT_, _E_, _ELLIPSIS_, _EQUAL_, _H_, _LR_PAIRS, \
15
15
  _N_, _name_, _not_scalar_, _PERCENT_, _SPACE_, \
@@ -22,7 +22,7 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
22
22
  from math import fabs, log10 as _log10
23
23
 
24
24
  __all__ = _ALL_LAZY.streprs
25
- __version__ = '24.11.26'
25
+ __version__ = '25.04.14'
26
26
 
27
27
  _at_ = 'at' # PYCHOK used!
28
28
  _EN_PREC = 6 # max MGRS/OSGR precision, 1 micrometer
@@ -82,7 +82,7 @@ class Fstr(str):
82
82
  @raise ValueError: Invalid B{C{arg}}.
83
83
  '''
84
84
  def _error(arg):
85
- n = _DOT_(Fstr.__name__, self.name or self)
85
+ n = _DOT_(typename(Fstr), self.name or self)
86
86
  return _SPACE_(n, _PERCENT_, repr(arg))
87
87
 
88
88
  prec = 6 # default std %f and %F
@@ -105,7 +105,7 @@ class _Sub(str):
105
105
  '''
106
106
  # see .ellipsoidalNvector.LatLon.deltaTo
107
107
  def __call__(self, *Classes):
108
- t = _or(*(C.__name__ for C in Classes))
108
+ t = _or(*map(typename, Classes))
109
109
  return str.__mod__(self, t or MISSING)
110
110
 
111
111
 
@@ -148,9 +148,10 @@ class Fmt(object):
148
148
  zone = _Fmt('%02d') # .epsg, .mgrs, .utmupsBase
149
149
 
150
150
  def __init__(self):
151
- for n, a in self.__class__.__dict__.items():
151
+ for n, a in type(self).__dict__.items():
152
152
  if isinstance(a, (Fstr, _Fmt)):
153
153
  setattr(a, _name_, n)
154
+ self.__name__ = typename(type(self))
154
155
 
155
156
  def __call__(self, obj, prec=9):
156
157
  '''Return C{str(B{obj})} or C{repr(B{obj})}.
@@ -182,15 +183,14 @@ class Fmt(object):
182
183
  '''
183
184
  return self.ANGLE(_SPACE_((text or inst), _at_, hex(id(inst))))
184
185
 
185
- Fmt = Fmt() # PYCHOK singleton
186
- Fmt.__name__ = Fmt.__class__.__name__
186
+ Fmt = Fmt() # PYCHOK singleton
187
187
 
188
- _DOTSTAR_ = Fmt.DOT(_STAR_)
188
+ _DOTSTAR_ = Fmt.DOT(_STAR_) # in _streprs above
189
189
  # formats %G and %g drop all trailing zeros and the
190
190
  # decimal point, making the float appear as an int
191
- _Gg = (Fmt.G, Fmt.g)
192
- _FfEeGg = (Fmt.F, Fmt.f, Fmt.E, Fmt.e) + _Gg # float formats
193
- _Fspec_ = NN('[%[<flags>][<width>]', _DOTSTAR_, ']', _BAR_.join(_FfEeGg)) # in testStreprs
191
+ _Gg = (Fmt.G, Fmt.g)
192
+ _FfEeGg = (Fmt.F, Fmt.f, Fmt.E, Fmt.e) + _Gg # float formats
193
+ _Fspec_ = NN('[%[<flags>][<width>]', _DOTSTAR_, ']', _BAR_.join(_FfEeGg)) # in testStreprs
194
194
 
195
195
  del _convergence_, _distant_, _e_, _eps_, _exceeds_, _EQUALSPACED_,\
196
196
  _f_, _F_, _g_, _limit_, _PAREN_g, _RESIDUAL_
@@ -561,14 +561,14 @@ def unstr(where, *args, **kwds_):
561
561
  t = reprs(args, fmt=g) if args else ()
562
562
  if kwds:
563
563
  t += pairs(itemsorted(kwds), fmt=g)
564
- n = where if isstr(where) else _DUNDER_nameof(where) # _NN_
564
+ n = where if isstr(where) else typename(where) # _NN_
565
565
  if C and hasattr(C, n):
566
566
  try: # bound method of class C?
567
567
  where = where.__func__
568
568
  except AttributeError:
569
569
  pass # method of C?
570
570
  if getattr(C, n, None) is where:
571
- n = _DOT_(_DUNDER_nameof(C), n)
571
+ n = _DOT_(typename(C), n)
572
572
  return Fmt.PAREN(n, _COMMASPACE_.join(t))
573
573
 
574
574