pygeodesy 25.4.25__py2.py3-none-any.whl → 25.5.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 (85) hide show
  1. pygeodesy/__init__.py +191 -189
  2. pygeodesy/__main__.py +2 -2
  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/basics.py +1 -1
  12. pygeodesy/booleans.py +8 -8
  13. pygeodesy/cartesianBase.py +7 -6
  14. pygeodesy/clipy.py +2 -2
  15. pygeodesy/constants.py +2 -2
  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 +15 -26
  24. pygeodesy/ecefLocals.py +186 -0
  25. pygeodesy/ellipsoidalBase.py +2 -2
  26. pygeodesy/ellipsoidalBaseDI.py +7 -6
  27. pygeodesy/ellipsoidalExact.py +3 -3
  28. pygeodesy/ellipsoidalNvector.py +4 -4
  29. pygeodesy/ellipsoidalVincenty.py +15 -14
  30. pygeodesy/ellipsoids.py +23 -30
  31. pygeodesy/elliptic.py +2 -2
  32. pygeodesy/errors.py +1 -1
  33. pygeodesy/etm.py +2 -2
  34. pygeodesy/fmath.py +28 -13
  35. pygeodesy/formy.py +2 -2
  36. pygeodesy/frechet.py +5 -5
  37. pygeodesy/fstats.py +2 -2
  38. pygeodesy/fsums.py +38 -29
  39. pygeodesy/gars.py +2 -3
  40. pygeodesy/geodesici.py +4 -4
  41. pygeodesy/geodesicx/__init__.py +3 -3
  42. pygeodesy/geodesicx/gx.py +2 -2
  43. pygeodesy/geodesicx/gxarea.py +2 -2
  44. pygeodesy/geodesicx/gxline.py +2 -2
  45. pygeodesy/geoids.py +5 -5
  46. pygeodesy/hausdorff.py +4 -4
  47. pygeodesy/heights.py +2 -2
  48. pygeodesy/iters.py +1 -1
  49. pygeodesy/karney.py +2 -2
  50. pygeodesy/ktm.py +2 -2
  51. pygeodesy/latlonBase.py +10 -8
  52. pygeodesy/lazily.py +46 -22
  53. pygeodesy/lcc.py +2 -2
  54. pygeodesy/ltp.py +54 -57
  55. pygeodesy/ltpTuples.py +34 -35
  56. pygeodesy/mgrs.py +3 -3
  57. pygeodesy/named.py +2 -147
  58. pygeodesy/namedTuples.py +3 -3
  59. pygeodesy/nvectorBase.py +2 -2
  60. pygeodesy/osgr.py +2 -2
  61. pygeodesy/points.py +2 -3
  62. pygeodesy/props.py +16 -16
  63. pygeodesy/resections.py +90 -82
  64. pygeodesy/rhumb/aux_.py +2 -2
  65. pygeodesy/rhumb/bases.py +3 -3
  66. pygeodesy/rhumb/ekx.py +3 -4
  67. pygeodesy/rhumb/solve.py +2 -2
  68. pygeodesy/simplify.py +2 -2
  69. pygeodesy/solveBase.py +2 -2
  70. pygeodesy/sphericalBase.py +6 -6
  71. pygeodesy/sphericalNvector.py +2 -2
  72. pygeodesy/sphericalTrigonometry.py +6 -5
  73. pygeodesy/trf.py +4 -4
  74. pygeodesy/triaxials.py +2 -2
  75. pygeodesy/units.py +7 -8
  76. pygeodesy/utily.py +2 -2
  77. pygeodesy/utmupsBase.py +55 -33
  78. pygeodesy/vector2d.py +16 -10
  79. pygeodesy/vector3d.py +3 -3
  80. pygeodesy/webmercator.py +2 -2
  81. {pygeodesy-25.4.25.dist-info → pygeodesy-25.5.25.dist-info}/METADATA +20 -19
  82. pygeodesy-25.5.25.dist-info/RECORD +119 -0
  83. pygeodesy-25.4.25.dist-info/RECORD +0 -118
  84. {pygeodesy-25.4.25.dist-info → pygeodesy-25.5.25.dist-info}/WHEEL +0 -0
  85. {pygeodesy-25.4.25.dist-info → pygeodesy-25.5.25.dist-info}/top_level.txt +0 -0
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, \
@@ -18,12 +18,11 @@ from pygeodesy.constants import EPS, EPS0, EPS02, INT0, PI, PI2, PI_2, PI_4, \
18
18
  _16_0, _180_0, _360_0, isnear0, _over, _umod_360
19
19
  from pygeodesy.errors import _and, _or, TriangleError, _ValueError, _xcallable, \
20
20
  _xkwds, _xkwds_pop2
21
- from pygeodesy.fmath import favg, Fdot, fidw, fmean, hypot, hypot2_
21
+ from pygeodesy.fmath import favg, Fdot, Fdot_, fidw, _fma, fmean, hypot, hypot2_
22
22
  from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1, fsum1f_
23
23
  # from pygeodesy.internals import typename # from .basics
24
24
  from pygeodesy.interns import _a_, _A_, _area_, _b_, _B_, _c_, _C_, _coincident_, \
25
- _colinear_, _d_, _invalid_, _negative_, _not_, \
26
- _rIn_, _SPACE_
25
+ _colinear_, _d_, _invalid_, _negative_, _rIn_, _SPACE_
27
26
  # from pygeodesy.lazily import _ALL_LAZY # from .basics
28
27
  from pygeodesy.named import _NamedTuple, _Pass, Fmt
29
28
  # from pygeodesy.streprs import Fmt # from .named
@@ -35,7 +34,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d
35
34
  from math import cos, degrees, fabs, radians, sin, sqrt
36
35
 
37
36
  __all__ = _ALL_LAZY.resections
38
- __version__ = '25.04.14'
37
+ __version__ = '25.05.12'
39
38
 
40
39
  _concyclic_ = 'concyclic'
41
40
  _PA_ = 'PA'
@@ -43,7 +42,6 @@ _PB_ = 'PB'
43
42
  _PC_ = 'PC'
44
43
  _pointH_ = 'pointH'
45
44
  _pointP_ = 'pointP'
46
- _positive_ = 'positive'
47
45
  _radA_ = 'radA'
48
46
  _radB_ = 'radB'
49
47
  _radC_ = 'radC'
@@ -170,11 +168,9 @@ def cassini(pointA, pointB, pointC, alpha, beta, useZ=False, **Clas_and_kwds):
170
168
 
171
169
  A, B, C = _ABC3(useZ, pointA, pointB, pointC)
172
170
  try:
173
- sa, sb = map1(float, alpha, beta)
174
- if min(sa, sb) < 0:
175
- raise ValueError(_negative_)
171
+ sa, sb = _noneg(alpha, beta)
176
172
  if fsumf_(_360_0, -sa, -sb) < EPS0:
177
- raise ValueError()
173
+ raise ValueError(_colinear_)
178
174
 
179
175
  x1, y1 = _H(A, C, sa)
180
176
  x2, y2 = _H(B, C, -sb)
@@ -253,15 +249,15 @@ def collins5(pointA, pointB, pointC, alpha, beta, useZ=False, **Clas_and_kwds):
253
249
 
254
250
  def _xyz(d, r, A, B, C, useZ):
255
251
  s, c = sincos2(r)
256
- x = d * s + A.x # fma(d, s, A.x)
257
- y = d * c + A.y # fma(d, c, A.y)
252
+ x = _fma(d, s, A.x)
253
+ y = _fma(d, c, A.y)
258
254
  z = _zidw(x, y, useZ, A, B, C)
259
255
  return x, y, z
260
256
 
261
257
  A, B, C = _ABC3(useZ, pointA, pointB, pointC)
262
258
  try:
263
- ra, rb = radians(alpha), radians(beta)
264
- if min(ra, rb) < 0:
259
+ ra, rb = t = radians(alpha), radians(beta)
260
+ if min(t) < 0:
265
261
  raise ValueError(_negative_)
266
262
 
267
263
  sra, srH = sin(ra), sin(ra + rb - PI) # rH = PI - ((PI - ra) + (PI - rb))
@@ -294,6 +290,15 @@ def collins5(pointA, pointB, pointC, alpha, beta, useZ=False, **Clas_and_kwds):
294
290
  alpha=alpha, beta=beta, cause=x)
295
291
 
296
292
 
293
+ def _noneg(*xs):
294
+ '''(INTERNAL) Return non-negative C{float}s.
295
+ '''
296
+ xs = tuple(map(float, xs))
297
+ if min(xs) < 0:
298
+ raise ValueError(_negative_)
299
+ return xs
300
+
301
+
297
302
  def pierlot(point1, point2, point3, alpha12, alpha23, useZ=False, eps=EPS,
298
303
  **Clas_and_kwds):
299
304
  '''3-Point resection using U{Pierlot<http://www.Telecom.ULg.ac.BE/publi/publications/
@@ -342,7 +347,7 @@ def pierlot(point1, point2, point3, alpha12, alpha23, useZ=False, eps=EPS,
342
347
  if eps > 0:
343
348
  return c / (min(s, -eps) if s < 0 else max(s, eps))
344
349
  t = Fmt.PARENSPACED(eps=eps)
345
- raise ValueError(_SPACE_(t, _not_, _positive_))
350
+ raise ValueError(_SPACE_(t, _invalid_))
346
351
 
347
352
  B1, B2, B3 = _B3(useZ, point1, point2, point3)
348
353
  try:
@@ -400,8 +405,8 @@ def _pierlot3(B1, B2, B3, a12, a23, useZ, _cot):
400
405
  # = (x31 - x23) * (y12 - y23) - (x12 - x23) * (y31 - y23)
401
406
  # x = (d * B2.x + K * Y12_23).fover(d)
402
407
  # y = (d * B2.y - K * X12_23).fover(d)
403
- x, y = _pierlotxy2(B2, -K, Y12_23, X12_23, (X31_23 * Y12_23 -
404
- X12_23 * Y31_23))
408
+ x, y = _pierlotxy2(B2, -K, Y12_23, X12_23, Fdot_(X31_23, Y12_23,
409
+ -X12_23, Y31_23))
405
410
  else:
406
411
  x, y, _ = B2.xyz3
407
412
  return x, y, _zidw(x, y, useZ, B1, B2, B3)
@@ -492,11 +497,11 @@ def _pierlotx3(a_z_Bs, useZ, _cot, Cs):
492
497
  if K:
493
498
  cot23 = _cot(*sincos2d(a23))
494
499
 
495
- # x23 = x2_ + cot23 * y2_
496
- # y23 = y2_ - cot23 * x2_
500
+ # x23 = x2_ + cot23 * y2_ # _fma( cot23, y2_, x2_)
501
+ # y23 = y2_ - cot23 * x2_ # _fma(-cot23, x2_, y2_)
497
502
 
498
- # x31 = x1_ + cot23 * y1_
499
- # y31 = y1_ - cot23 * x1_
503
+ # x31 = x1_ + cot23 * y1_ # _fma( cot23, y1_, x1_)
504
+ # y31 = y1_ - cot23 * x1_ # _fma(-cot23, x1_, y1_)
500
505
 
501
506
  # x31 - x23 = x1_ + cot23 * y1_ - x2_ - cot23 * y2_
502
507
  X31_23 = _Fsumf_(x1_, cot23 * y1_, -x2_, -cot23 * y2_)
@@ -504,10 +509,10 @@ def _pierlotx3(a_z_Bs, useZ, _cot, Cs):
504
509
  Y31_23 = _Fsumf_(y1_, -cot23 * x1_, -y2_, cot23 * x2_)
505
510
 
506
511
  # d = (x31 - x23) * (x2_ - x1_) + (y31 - y23) * (y2_ - y1_)
507
- # x = (D * B3.x - K * Y31_23).fover(d)
508
- # y = (D * B3.y + K * X31_23).fover(d)
509
- x, y = _pierlotxy2(B3, K, Y31_23, X31_23, (X31_23 * _Fsumf_(x2_, -x1_) +
510
- Y31_23 * _Fsumf_(y2_, -y1_)))
512
+ # x = (d * B3.x - K * Y31_23).fover(d)
513
+ # y = (d * B3.y + K * X31_23).fover(d)
514
+ x, y = _pierlotxy2(B3, K, Y31_23, X31_23, Fdot_(X31_23, _Fsumf_(x2_, -x1_),
515
+ Y31_23, _Fsumf_(y2_, -y1_)))
511
516
  else:
512
517
  x, y, _ = B3.xyz3
513
518
  return x, y, _zidw(x, y, useZ, B1, B2, B3)
@@ -519,8 +524,8 @@ def _pierlotxy2(B, K, X, Y, D):
519
524
  d = float(D)
520
525
  if isnear0(d):
521
526
  raise ValueError(_or(_coincident_, _colinear_, _concyclic_))
522
- x = (D * B.x - K * X).fover(d)
523
- y = (D * B.y + K * Y).fover(d)
527
+ x = Fdot_(D, B.x, -K, X).fover(d)
528
+ y = Fdot_(D, B.y, K, Y).fover(d)
524
529
  return x, y
525
530
 
526
531
 
@@ -551,9 +556,7 @@ def snellius3(a, b, degC, alpha, beta):
551
556
  @see: Function L{wildberger3}.
552
557
  '''
553
558
  try:
554
- a, b, degC, alpha, beta = t = map1(float, a, b, degC, alpha, beta)
555
- if min(t) < 0:
556
- raise ValueError(_negative_)
559
+ a, b, degC, alpha, beta = _noneg(a, b, degC, alpha, beta)
557
560
  ra, rb, rC = map1(radians, alpha, beta, degC)
558
561
 
559
562
  r = fsum1f_(ra, rb, rC) * _0_5
@@ -705,17 +708,15 @@ def triAngle(a, b, c):
705
708
 
706
709
  def _triAngle(a, b, c):
707
710
  # (INTERNAL) To allow callers to embellish errors
708
- a, b, c = map1(float, a, b, c)
709
- if a < b:
711
+ a, b, c = _noneg(a, b, c)
712
+ if b > a:
710
713
  a, b = b, a
711
- if b < 0 or c < 0:
712
- raise ValueError(_negative_)
713
714
  if a < EPS0:
714
715
  raise ValueError(_coincident_)
715
716
  b_a = b / a
716
717
  if b_a < EPS0:
717
718
  raise ValueError(_coincident_)
718
- t = fsumf_(_1_0, b_a**2, -(c / a)**2) / (b_a * _2_0)
719
+ t = _Fsumf_(_1_0, b_a**2, -(c / a)**2).fover(b_a * _2_0)
719
720
  return acos1(t)
720
721
 
721
722
 
@@ -733,7 +734,7 @@ def triAngle5(a, b, c):
733
734
  C{radA}, C{radB} and C{radC} at triangle corners C{A}, C{B}
734
735
  and C{C}, all in C{radians}, the C{InCircle} radius C{rIn}
735
736
  aka C{inradius}, same units as triangle sides B{C{a}},
736
- B{C{b}} and B{C{c}} and the triangle C{area} in those same
737
+ B{C{b}} and B{C{c}} and the triangle C{area} in the same
737
738
  units I{squared}.
738
739
 
739
740
  @raise TriangleError: Invalid or negative B{C{a}}, B{C{b}} or B{C{c}}.
@@ -797,15 +798,15 @@ def triArea(a, b, c):
797
798
  try:
798
799
  r, y, x = sorted(map1(float, a, b, c))
799
800
  if r > 0: # r = min(a, b, c)
800
- ab = x - y
801
- bc = y - r
802
- y += r
803
- r = (x + y) * (r - ab) * (r + ab) * (x + bc)
801
+ s = r
802
+ d = x - y
803
+ r = (s + d) * (s - d)
804
804
  if r:
805
- r = sqrt(r / _16_0)
806
- elif r < 0:
805
+ y += x
806
+ r *= (y + s) * (y - s)
807
+ if r < 0:
807
808
  raise ValueError(_negative_)
808
- return r
809
+ return sqrt(r / _16_0) if r else _0_0
809
810
 
810
811
  except (TypeError, ValueError) as x:
811
812
  raise TriangleError(a=a, b=b, c=c, cause=x)
@@ -837,11 +838,8 @@ def triSide(a, b, radC):
837
838
 
838
839
  def _triSide(a, b, radC):
839
840
  # (INTERNAL) To allow callers to embellish errors
840
- a, b, r = t = map1(float, a, b, radC)
841
- if min(t) < 0:
842
- raise ValueError(_negative_)
843
-
844
- if a < b:
841
+ a, b, r = _noneg(a, b, radC)
842
+ if b < a:
845
843
  a, b = b, a
846
844
  if a > EPS0:
847
845
  ba = b / a
@@ -880,18 +878,21 @@ def triSide2(b, c, radB):
880
878
 
881
879
  def _triSide2(b, c, radB):
882
880
  # (INTERNAL) To allow callers to embellish errors
883
- b, c, rB = map1(float, b, c, radB)
884
- if min(b, c, rB) < 0:
885
- raise ValueError(_negative_)
881
+ b, c, rB = _noneg(b, c, radB)
886
882
  sB, cB = sincos2(rB)
887
- if isnear0(sB):
888
- if not isnear0(b):
883
+ if isnear0(b) or isnear0(sB):
884
+ if isnear0(b) and isnear0(sB):
885
+ if cB < 0:
886
+ rA = PI
887
+ a = b + c
888
+ else:
889
+ rA = _0_0
890
+ a = fabs(b - c)
891
+ else:
889
892
  raise ValueError(_invalid_)
890
- a, rA = ((b + c), PI) if cB < 0 else (fabs(b - c), _0_0)
891
- elif isnear0(b):
892
- raise ValueError(_invalid_)
893
893
  else:
894
- rA = fsumf_(PI, -rB, -asin1(c * sB / b))
894
+ rC = asin1(c * sB / b)
895
+ rA = max(fsumf_(PI, -rB, -rC), _0_0)
895
896
  a = sin(rA) * b / sB
896
897
  return TriSide2Tuple(a, rA, name=typename(triSide2))
897
898
 
@@ -918,17 +919,19 @@ def triSide4(radA, radB, c):
918
919
  and functions L{sqrt_a}, L{triSide} and L{triSide2}.
919
920
  '''
920
921
  try:
921
- rA, rB, c = map1(float, radA, radB, c)
922
+ rA, rB, c = _noneg(radA, radB, c)
922
923
  rC = fsumf_(PI, -rA, -rB)
923
- if min(rC, rA, rB, c) < 0:
924
+ if rC < 0:
924
925
  raise ValueError(_negative_)
925
926
  sa, ca, sb, cb = sincos2_(rA, rB)
926
927
  sc = fsum1f_(sa * cb, sb * ca)
927
928
  if sc < EPS0 or min(sa, sb) < 0:
928
929
  raise ValueError(_invalid_)
929
- sc = c / sc
930
- return TriSide4Tuple((sa * sc), (sb * sc), rC, (sa * sb * sc),
931
- 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))
932
935
 
933
936
  except (TypeError, ValueError) as x:
934
937
  raise TriangleError(radA=radA, radB=radB, c=c, cause=x)
@@ -947,7 +950,8 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
947
950
  @arg alpha: Angle subtended by triangle side B{C{b}} (C{degrees}, non-negative).
948
951
  @arg beta: Angle subtended by triangle side B{C{a}} (C{degrees}, non-negative).
949
952
  @kwarg R3: Callable to determine C{R3} from C{(R3 - C)**2 = D}, typically standard
950
- 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>}.
951
955
 
952
956
  @return: L{Survey3Tuple}C{(PA, PB, PC)} with distance from survey point C{P} to
953
957
  each of the triangle corners C{A}, C{B} and C{C}, same units as B{C{a}},
@@ -961,43 +965,47 @@ def wildberger3(a, b, c, alpha, beta, R3=min):
961
965
  U{Devine Proportions, page 252<http://www.MS.LT/derlius/WildbergerDivineProportions.pdf>}
962
966
  and function L{snellius3}.
963
967
  '''
964
- def _s(x):
968
+ def _sin2(x):
965
969
  return sin(x)**2
966
970
 
967
971
  def _vpa(r3, q2, q3, s2, s3):
968
- r1 = s2 * q3 / s3
969
- r = r1 * r3 * _4_0
970
- n = (r - _Fsumf_(r1, r3, -q2)**2).fover(s3)
971
- if n < 0 or r < EPS0:
972
+ r4 = r3 * _4_0
973
+ s4 = r4 * s2
974
+ if isnear0(s4):
975
+ raise ValueError(_coincident_)
976
+ r1 = s2 * q3 / s3
977
+ N2 = _Fsumf_(r1, r3, -q2)**2
978
+ n = (r4 * r1 - N2).fover(s4)
979
+ if n < 0:
972
980
  raise ValueError(_coincident_)
973
- return sqrt((n / r) * q3) if n else _0_0
981
+ return sqrt(n) if n else _0_0
974
982
 
975
983
  try:
976
- a, b, c, da, db = q = map1(float, a, b, c, alpha, beta)
977
- if min(q) < 0:
978
- raise ValueError(_negative_)
979
-
984
+ a, b, c, da, db = _noneg(a, b, c, alpha, beta)
980
985
  q1, q2, q3 = q = a**2, b**2, c**2
981
986
  if min(q) < EPS02:
982
987
  raise ValueError(_coincident_)
983
988
 
984
989
  ra, rb = map1(radians, da, db)
985
- 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!
986
991
  if min(s) < EPS02:
987
992
  raise ValueError(_or(_coincident_, _colinear_))
988
-
989
- q4 = hypot2_(*q) * _2_0 # a**4 + ...
990
- Qs = _Fsumf_(*q) # == hypot2_(a, b, c)
991
- d0 = (Qs**2 - q4).fmul(s1 * s2).fover(s3)
992
- if d0 < 0:
993
- raise ValueError(_negative_)
994
993
  s += _Fsumf_(*s), # == fsum1(s),
995
- C0 = Fdot(s, q1, q2, q3, -Qs * _0_5)
994
+
995
+ Q = _Fsumf_(*q) # == a**2 + b**2 + ...
996
+ C0 = Fdot(s, q1, q2, q3, -Q * _0_5)
996
997
  r3 = C0.fover(-s3) # C0 /= -s3
998
+
999
+ Q *= Q # Q**2 - 2 * (a**4 + b**4 ...
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
1007
+ elif d0 < (-EPS02):
1008
+ raise ValueError(_negative_)
1001
1009
 
1002
1010
  pa = _vpa(r3, q2, q3, s2, s3)
1003
1011
  pb = _vpa(r3, q1, q3, s1, s3)
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.12'
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):
@@ -31,7 +31,7 @@ Also note that on a spherical earth model, an n-vector is equivalent
31
31
  to a normalised version of an (ECEF) cartesian coordinate.
32
32
  '''
33
33
  # make sure int/int division yields float quosient, see .basics
34
- from __future__ import division as _; del _ # PYCHOK semicolon
34
+ from __future__ import division as _; del _ # noqa: E702 ;
35
35
 
36
36
  from pygeodesy.basics import _isin, _xinstanceof, typename
37
37
  from pygeodesy.constants import EPS, EPS0, PI, PI2, PI_2, R_M, \
@@ -62,7 +62,7 @@ from pygeodesy.utily import atan2, degrees360, sincos2, sincos2_, sincos2d, \
62
62
  # from math import fabs # from utily
63
63
 
64
64
  __all__ = _ALL_LAZY.sphericalNvector
65
- __version__ = '25.04.14'
65
+ __version__ = '25.05.12'
66
66
 
67
67
  _lines_ = 'lines'
68
68
 
@@ -14,7 +14,7 @@ I{(C) Chris Veness 2011-2024} published under the same MIT Licence**, see
14
14
  U{Latitude/Longitude<https://www.Movable-Type.co.UK/scripts/latlong.html>}.
15
15
  '''
16
16
  # make sure int/int division yields float quotient, see .basics
17
- from __future__ import division as _; del _ # PYCHOK semicolon
17
+ from __future__ import division as _; del _ # noqa: E702 ;
18
18
 
19
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, \
@@ -34,8 +34,9 @@ from pygeodesy.interns import _1_, _2_, _coincident_, _composite_, _colinear_, \
34
34
  _concentric_, _convex_, _end_, _infinite_, \
35
35
  _invalid_, _line_, _near_, _null_, _parallel_, \
36
36
  _point_, _SPACE_, _too_
37
+ from pygeodesy.latlonBase import _trilaterate5
37
38
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _ALL_OTHER
38
- # from pygeodesy.nvectorBase import NvectorBase, sumOf # _MODE
39
+ # from pygeodesy.nvectorBase import NvectorBase, sumOf # _MODS
39
40
  from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, NearestOn3Tuple, \
40
41
  Triangle7Tuple, Triangle8Tuple
41
42
  from pygeodesy.points import ispolar, nearestOn5 as _nearestOn5, \
@@ -43,10 +44,10 @@ from pygeodesy.points import ispolar, nearestOn5 as _nearestOn5, \
43
44
  from pygeodesy.props import deprecated_function, deprecated_method
44
45
  from pygeodesy.sphericalBase import _m2radians, CartesianSphericalBase, \
45
46
  _intersecant2, LatLonSphericalBase, \
46
- _rads3, _radians2m, _trilaterate5
47
+ _rads3, _radians2m
47
48
  # from pygeodesy.streprs import Fmt as _Fmt # from .points XXX shadowed
48
49
  from pygeodesy.units import Bearing_, Height, _isDegrees, _isRadius, Lamd, \
49
- Phid, Radius_, Scalar
50
+ Phid, Radius_, Scalar
50
51
  from pygeodesy.utily import acos1, asin1, atan1d, atan2, atan2d, degrees90, \
51
52
  degrees180, degrees2m, m2radians, radiansPI2, \
52
53
  sincos2_, tan_2, unrollPI, _unrollon, _unrollon3, \
@@ -56,7 +57,7 @@ from pygeodesy.vector3d import sumOf, Vector3d
56
57
  from math import asin, cos, degrees, fabs, radians, sin
57
58
 
58
59
  __all__ = _ALL_LAZY.sphericalTrigonometry
59
- __version__ = '25.04.14'
60
+ __version__ = '25.05.12'
60
61
 
61
62
  _PI_EPS4 = PI - EPS4
62
63
  if _PI_EPS4 >= PI:
pygeodesy/trf.py CHANGED
@@ -93,7 +93,7 @@ from math import ceil as _ceil, fabs
93
93
  # import operator as _operator # from .datums
94
94
 
95
95
  __all__ = _ALL_LAZY.trf
96
- __version__ = '25.04.14'
96
+ __version__ = '25.05.12'
97
97
 
98
98
  _EP0CH = Epoch(0, low=0)
99
99
  _Es = {_EP0CH: _EP0CH} # L{Epoch}s, deleted below
@@ -148,7 +148,7 @@ def _E(epoch): # deleted below
148
148
  '''(INTERNAL) De-dup L{Epochs}s.
149
149
  '''
150
150
  e = Epoch(_F(epoch))
151
- return _Es.setdefault(e, e) # PYCHOK del
151
+ return _Es.setdefault(e, e) # noqa: F821 del
152
152
 
153
153
 
154
154
  def _P(ps, name, _Ps): # deleted below
@@ -1299,11 +1299,11 @@ def _trfX(n1, n2, raiser=True, **epoch_xform_rates):
1299
1299
 
1300
1300
 
1301
1301
  def _X(*ps): # deleted below
1302
- return _P(ps, _xform_, _Xs) # PYCHOK del
1302
+ return _P(ps, _xform_, _Xs) # noqa: F821 del
1303
1303
 
1304
1304
 
1305
1305
  def _R(*ps): # deleted below
1306
- return _P(ps, _rates_, _Rs) # PYCHOK del
1306
+ return _P(ps, _rates_, _Rs) # noqa: F821 del
1307
1307
 
1308
1308
 
1309
1309
  _P_0_0s = TRFXform7Tuple(_0_0s(len(_Names7)), name='unity')
pygeodesy/triaxials.py CHANGED
@@ -28,7 +28,7 @@ see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
28
28
  @var Triaxials.WGS84_35: Triaxial(name='WGS84_35', a=6378172, b=6378102, c=6356752.314245179, e2ab=0.00002195, e2bc=0.006683478, e2ac=0.006705281, volume=1083207319768789942272, area=510065621722018.125, area_p=510065626587483.3125)
29
29
  '''
30
30
  # make sure int/int division yields float quotient, see .basics
31
- from __future__ import division as _; del _ # PYCHOK semicolon
31
+ from __future__ import division as _; del _ # noqa: E702 ;
32
32
 
33
33
  from pygeodesy.basics import _isin, isLatLon, isscalar
34
34
  from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, INT0, PI2, PI_3, PI4, \
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
59
59
  from math import fabs, sqrt
60
60
 
61
61
  __all__ = _ALL_LAZY.triaxials
62
- __version__ = '25.04.14'
62
+ __version__ = '25.05.12'
63
63
 
64
64
  _not_ordered_ = _not_('ordered')
65
65
  _omega_ = 'omega'