pygeodesy 24.6.9__py2.py3-none-any.whl → 24.7.7__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 (87) hide show
  1. {PyGeodesy-24.6.9.dist-info → PyGeodesy-24.7.7.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.7.7.dist-info/RECORD +117 -0
  3. pygeodesy/__init__.py +39 -32
  4. pygeodesy/__main__.py +6 -1
  5. pygeodesy/albers.py +2 -2
  6. pygeodesy/auxilats/__init__.py +1 -1
  7. pygeodesy/auxilats/auxAngle.py +40 -39
  8. pygeodesy/auxilats/auxDLat.py +3 -2
  9. pygeodesy/auxilats/auxLat.py +16 -18
  10. pygeodesy/auxilats/auxily.py +1 -1
  11. pygeodesy/azimuthal.py +10 -10
  12. pygeodesy/basics.py +16 -4
  13. pygeodesy/booleans.py +4 -4
  14. pygeodesy/cartesianBase.py +11 -14
  15. pygeodesy/css.py +14 -18
  16. pygeodesy/datums.py +6 -6
  17. pygeodesy/deprecated/__init__.py +1 -1
  18. pygeodesy/deprecated/classes.py +25 -4
  19. pygeodesy/deprecated/datum.py +3 -3
  20. pygeodesy/deprecated/functions.py +6 -8
  21. pygeodesy/dms.py +23 -27
  22. pygeodesy/ecef.py +4 -4
  23. pygeodesy/elevations.py +4 -4
  24. pygeodesy/ellipsoidalBase.py +23 -28
  25. pygeodesy/ellipsoidalBaseDI.py +19 -23
  26. pygeodesy/ellipsoidalExact.py +3 -3
  27. pygeodesy/ellipsoidalGeodSolve.py +15 -23
  28. pygeodesy/ellipsoidalKarney.py +37 -60
  29. pygeodesy/ellipsoidalNvector.py +38 -44
  30. pygeodesy/ellipsoidalVincenty.py +11 -14
  31. pygeodesy/ellipsoids.py +107 -101
  32. pygeodesy/errors.py +109 -48
  33. pygeodesy/etm.py +32 -44
  34. pygeodesy/formy.py +55 -58
  35. pygeodesy/frechet.py +18 -20
  36. pygeodesy/fsums.py +3 -3
  37. pygeodesy/gars.py +3 -4
  38. pygeodesy/geodesici.py +1696 -0
  39. pygeodesy/geodesicw.py +15 -15
  40. pygeodesy/geodesicx/__init__.py +4 -4
  41. pygeodesy/geodesicx/gx.py +34 -55
  42. pygeodesy/geodesicx/gxbases.py +20 -8
  43. pygeodesy/geodesicx/gxline.py +93 -88
  44. pygeodesy/geodsolve.py +108 -59
  45. pygeodesy/geohash.py +26 -34
  46. pygeodesy/geoids.py +28 -37
  47. pygeodesy/hausdorff.py +17 -18
  48. pygeodesy/heights.py +2 -2
  49. pygeodesy/internals.py +46 -13
  50. pygeodesy/interns.py +2 -2
  51. pygeodesy/karney.py +78 -15
  52. pygeodesy/ktm.py +13 -16
  53. pygeodesy/latlonBase.py +17 -19
  54. pygeodesy/lazily.py +28 -25
  55. pygeodesy/lcc.py +28 -31
  56. pygeodesy/ltp.py +7 -8
  57. pygeodesy/ltpTuples.py +71 -73
  58. pygeodesy/mgrs.py +8 -9
  59. pygeodesy/named.py +19 -10
  60. pygeodesy/nvectorBase.py +9 -10
  61. pygeodesy/osgr.py +9 -9
  62. pygeodesy/points.py +6 -6
  63. pygeodesy/rhumb/__init__.py +1 -1
  64. pygeodesy/rhumb/aux_.py +5 -5
  65. pygeodesy/rhumb/bases.py +30 -31
  66. pygeodesy/rhumb/ekx.py +3 -4
  67. pygeodesy/rhumb/solve.py +21 -22
  68. pygeodesy/solveBase.py +177 -123
  69. pygeodesy/sphericalBase.py +10 -11
  70. pygeodesy/sphericalNvector.py +13 -13
  71. pygeodesy/sphericalTrigonometry.py +86 -97
  72. pygeodesy/streprs.py +4 -34
  73. pygeodesy/triaxials.py +48 -43
  74. pygeodesy/units.py +208 -275
  75. pygeodesy/unitsBase.py +115 -107
  76. pygeodesy/ups.py +26 -31
  77. pygeodesy/utily.py +8 -8
  78. pygeodesy/utm.py +35 -40
  79. pygeodesy/utmups.py +43 -46
  80. pygeodesy/utmupsBase.py +8 -9
  81. pygeodesy/vector3d.py +26 -27
  82. pygeodesy/vector3dBase.py +6 -7
  83. pygeodesy/webmercator.py +19 -21
  84. pygeodesy/wgrs.py +18 -20
  85. PyGeodesy-24.6.9.dist-info/RECORD +0 -116
  86. {PyGeodesy-24.6.9.dist-info → PyGeodesy-24.7.7.dist-info}/WHEEL +0 -0
  87. {PyGeodesy-24.6.9.dist-info → PyGeodesy-24.7.7.dist-info}/top_level.txt +0 -0
pygeodesy/errors.py CHANGED
@@ -14,19 +14,20 @@ C{PYGEODESY_EXCEPTION_CHAINING=std} or to any non-empty string.
14
14
  # from pygeodesy.basics import isint, isodd, issubclassof, itemsorted, _xinstanceof, _zip # _MODS
15
15
  # from pygeodesy.ellipsoidalBase import CartesianEllipsoidalBase, LatLonEllipsoidalBase # _MODS
16
16
  # from pygeodesy import errors # _MODS, _MODS.getattr
17
- from pygeodesy.internals import _plural, _tailof
17
+ from pygeodesy.internals import _dunder_nameof_, _plural, _tailof
18
18
  from pygeodesy.interns import MISSING, NN, _a_, _an_, _and_, _clip_, _COLON_, _COLONSPACE_, \
19
19
  _COMMASPACE_, _datum_, _ellipsoidal_, _incompatible_, _invalid_, \
20
- _keyword_, _len_, _not_, _or_, _SPACE_, _specified_, _UNDER_, \
21
- _vs_, _with_
20
+ _keyword_, _LatLon_, _len_, _not_, _or_, _SPACE_, _specified_, \
21
+ _UNDER_, _vs_, _with_
22
22
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _getenv, _PYTHON_X_DEV
23
- # from pygeodesy.streprs import Fmt, unstr # _MODS
23
+ # from pygeodesy import streprs as _streprs # _MODS
24
+ # from pygeodesy.unitsBase import Str # _MODS
24
25
  # from pygeodesy.vector3dBase import Vector3dBase # _MODS
25
26
 
26
27
  from copy import copy as _copy
27
28
 
28
29
  __all__ = _ALL_LAZY.errors # _ALL_DOCS('_InvalidError', '_IsnotError') _under
29
- __version__ = '24.06.08'
30
+ __version__ = '24.07.07'
30
31
 
31
32
  _argument_ = 'argument'
32
33
  _box_ = 'box'
@@ -35,6 +36,7 @@ _limiterrors = True # in .formy
35
36
  _name_value_ = repr('name=value')
36
37
  _rangerrors = True # in .dms
37
38
  _region_ = 'region'
39
+ _streprs = _MODS.into(streprs=__name__)
38
40
  _vs__ = _SPACE_(NN, _vs_, NN)
39
41
 
40
42
  try:
@@ -155,7 +157,7 @@ class _UnexpectedError(TypeError): # note, a TypeError!
155
157
  n = _and(a, _plural(_keyword_, n)) if n else a
156
158
  else:
157
159
  n = _plural(_SPACE_(_keyword_, _argument_), n)
158
- u = _MODS.streprs.unstr(_SPACE_(n, NN), *args, **kwds)
160
+ u = _streprs.unstr(_SPACE_(n, NN), *args, **kwds)
159
161
  # _error_init(TypeError, self, (u,), txt_not_=_expected_)
160
162
  TypeError.__init__(self, _SPACE_(u, _not_, _expected_))
161
163
 
@@ -208,8 +210,8 @@ class CrossError(_ValueError):
208
210
 
209
211
 
210
212
  class GeodesicError(_ValueError):
211
- '''Error raised for lack of convergence or other issues in L{pygeodesy.geodesicx},
212
- L{pygeodesy.geodesicw} or L{pygeodesy.karney}.
213
+ '''Error raised for convergence or other issues in L{geodesicx<pygeodesy.geodesicx>},
214
+ L{geodesicw<pygeodesy.geodesicw>} or L{karney<pygeodesy.karney>}.
213
215
  '''
214
216
  pass
215
217
 
@@ -243,17 +245,17 @@ class LenError(_ValueError): # in .ecef, .fmath, .heights, .iters, .named
243
245
 
244
246
  ns, vs, txt, x = _ns_vs_txt_x(**lens_txt)
245
247
  ns = _COMMASPACE_.join(ns)
246
- t = _MODS.streprs.Fmt.PAREN(where.__name__, ns)
248
+ t = _streprs.Fmt.PAREN(where.__name__, ns)
247
249
  vs = _vs__.join(map(str, vs))
248
250
  t = _SPACE_(t, _len_, vs)
249
251
  _ValueError.__init__(self, t, txt=txt, cause=x)
250
252
 
251
253
 
252
254
  class LimitError(_ValueError):
253
- '''Error raised for lat- or longitudinal values or deltas exceeding
254
- the given B{C{limit}} in functions L{pygeodesy.equirectangular},
255
- L{pygeodesy.equirectangular4}, C{nearestOn*} and C{simplify*}
256
- or methods with C{limit} or C{options} keyword arguments.
255
+ '''Error raised for lat- or longitudinal values or deltas exceeding the given
256
+ B{C{limit}} in functions L{equirectangular<pygeodesy.equirectangular>},
257
+ L{equirectangular4<pygeodesy.equirectangular4>}, C{nearestOn*} and
258
+ C{simplify*} or methods with C{limit} or C{options} keyword arguments.
257
259
 
258
260
  @see: Subclass L{UnitError}.
259
261
  '''
@@ -285,26 +287,25 @@ class PointsError(_ValueError): # in .clipy, .frechet, ...
285
287
 
286
288
 
287
289
  class RangeError(_ValueError):
288
- '''Error raised for lat- or longitude values outside the B{C{clip}},
289
- B{C{clipLat}}, B{C{clipLon}} in functions L{pygeodesy.parse3llh},
290
- L{pygeodesy.parseDMS}, L{pygeodesy.parseDMS2} and L{pygeodesy.parseRad}
291
- or the given B{C{limit}} in functions L{pygeodesy.clipDegrees} and
292
- L{pygeodesy.clipRadians}.
290
+ '''Error raised for lat- or longitude values outside the B{C{clip}}, B{C{clipLat}},
291
+ B{C{clipLon}} in functions L{parse3llh<pygeodesy.dms.parse3llh>}, L{parseDMS<pygeodesy.dms.parseDMS>},
292
+ L{parseDMS2<pygeodesy.dms.parseDMS2>} and L{parseRad<pygeodesy.dms.parseRad>} or the B{C{limit}} set
293
+ with functions L{clipDegrees<pygeodesy.dms.clipDegrees>} and L{clipRadians<pygeodesy.dms.clipRadians>}.
293
294
 
294
- @see: Function L{pygeodesy.rangerrors}.
295
+ @see: Function L{rangerrors<pygeodesy.errors.rangerrors>}.
295
296
  '''
296
297
  pass
297
298
 
298
299
 
299
300
  class RhumbError(_ValueError):
300
- '''Error raised for a L{pygeodesy.rhumb.aux_}, L{pygeodesy.rhumb.ekx}
301
- or L{pygeodesy.rhumb.solve} issue.
301
+ '''Error raised for a rhumb L{aux_<pygeodesy.rhumb.aux_>}, L{ekx<pygeodesy.rhumb.ekx>} or
302
+ L{solve<pygeodesy.rhumb.solve>} issue.
302
303
  '''
303
304
  pass
304
305
 
305
306
 
306
307
  class TriangleError(_ValueError): # in .resections, .vector2d
307
- '''Error raised for triangle, inter- or resection issues.
308
+ '''Error raised for triangle, intersection or resection issues.
308
309
  '''
309
310
  pass
310
311
 
@@ -330,15 +331,15 @@ class SciPyWarning(PointsError):
330
331
 
331
332
 
332
333
  class TRFError(_ValueError): # in .ellipsoidalBase, .trf, .units
333
- '''Terrestrial Reference Frame (TRF), L{Epoch}, L{RefFrame}
334
- or L{RefFrame} conversion issue.
334
+ '''Terrestrial Reference Frame (TRF), L{Epoch}, L{RefFrame} or L{RefFrame}
335
+ conversion issue.
335
336
  '''
336
337
  pass
337
338
 
338
339
 
339
340
  class UnitError(LimitError): # in .named, .units
340
- '''Default exception for L{units} issues for a value exceeding the
341
- C{low} or C{high} limit.
341
+ '''Default exception for L{units} issues for a value exceeding the C{low}
342
+ or C{high} limit.
342
343
  '''
343
344
  pass
344
345
 
@@ -460,8 +461,8 @@ def exception_chaining(exc=None):
460
461
  @return: If C{B{exc} is None}, return C{True} if exception
461
462
  chaining is enabled for PyGeodesy errors, C{False}
462
463
  if turned off and C{None} if not available. If
463
- B{C{exc}} is not C{None}, return it's error I{cause}
464
- or C{None}.
464
+ C{B{exc} is not None}, return it's error I{cause}
465
+ or C{None} if there is none.
465
466
 
466
467
  @note: To enable exception chaining for C{pygeodesy} errors,
467
468
  set env var C{PYGEODESY_EXCEPTION_CHAINING} to any
@@ -511,23 +512,22 @@ def isError(exc):
511
512
  _X(exc) if isinstance(exc, Exception) else None)
512
513
 
513
514
 
514
- def _IsnotError(*nouns, **name_value_Error_cause): # name=value [, Error=TypeError, cause=None]
515
+ def _IsnotError(*types__, **name_value_Error_cause): # name=value [, Error=TypeError, cause=None]
515
516
  '''Create a C{TypeError} for an invalid C{name=value} type.
516
517
 
517
- @arg nouns: One or more expected class or type names, usually nouns (C{str}).
518
+ @arg types__: One or more types or type names.
518
519
  @kwarg name_value_Error_cause: One C{B{name}=value} pair and optionally,
519
- keyword argument C{B{Error}=TypeError} to override the default
520
- and C{B{cause}=None} for exception chaining.
520
+ keyword arguments C{B{Error}=TypeError} and C{B{cause}=None}
521
+ for exception chaining.
521
522
 
522
523
  @return: A C{TypeError} or an B{C{Error}} instance.
523
524
  '''
524
- def _n_v_E_x(cause=None, Error=TypeError, **name_value):
525
- return _xkwds_item2(name_value) + (Error, cause)
525
+ x, kwds = _xkwds_pop2(name_value_Error_cause, cause=None)
526
+ E, kwds = _xkwds_pop2(kwds, Error=TypeError)
527
+ n, v = _xkwds_item2(kwds)
526
528
 
527
- n, v, E, x = _n_v_E_x(**name_value_Error_cause)
528
-
529
- n = _MODS.streprs.Fmt.PARENSPACED(n, repr(v))
530
- t = _not_(_an(_or(*nouns)) if nouns else _specified_)
529
+ n = _streprs.Fmt.PARENSPACED(n, repr(v))
530
+ t = _not_(_an(_or(*_dunder_nameof_(*types__))) if types__ else _specified_)
531
531
  return _XError(E, n, txt=t, cause=x)
532
532
 
533
533
 
@@ -553,14 +553,13 @@ def _or(*words):
553
553
  return _and_or(_or_, *words)
554
554
 
555
555
 
556
- def _parseX(parser, *args, **name_values_Error): # name=value[, ..., Error=ParseError]
556
+ def _parseX(parser, *args, **Error_name_values): # name=value[, ..., Error=ParseError]
557
557
  '''(INTERNAL) Invoke a parser and handle exceptions.
558
558
 
559
- @arg parser: The parser (C{callable}).
559
+ @arg parser: The parser (C{callable(*B{args}}).
560
560
  @arg args: Any B{C{parser}} arguments (any C{type}s).
561
- @kwarg name_values_Error: Any C{B{name}=value} pairs and
562
- optionally, C{B{Error}=ParseError} keyword
563
- argument to override the default.
561
+ @kwarg Error_name_values: Optional C{B{Error}=ParseError}
562
+ and number of C{B{name}=value} pairs.
564
563
 
565
564
  @return: Parser result.
566
565
 
@@ -570,7 +569,7 @@ def _parseX(parser, *args, **name_values_Error): # name=value[, ..., Error=Pars
570
569
  return parser(*args)
571
570
  except Exception as x:
572
571
  E = type(x) if isError(x) else ParseError
573
- E, kwds = _xkwds_pop2(name_values_Error, Error=E)
572
+ E, kwds = _xkwds_pop2(Error_name_values, Error=E)
574
573
  raise _XError(E, **_xkwds(kwds, cause=x))
575
574
 
576
575
 
@@ -603,11 +602,11 @@ def _xAssertionError(where, *args, **kwds):
603
602
  '''(INTERNAL) Embellish an C{AssertionError} with/-out exception chaining.
604
603
  '''
605
604
  x, kwds = _xkwds_pop2(kwds, cause=None)
606
- w = _MODS.streprs.unstr(where, *args, **kwds)
605
+ w = _streprs.unstr(where, *args, **kwds)
607
606
  return _AssertionError(w, txt=None, cause=x)
608
607
 
609
608
 
610
- def _xattr(obj, **name_default): # see .strerprs._xattrs
609
+ def _xattr(obj, **name_default):
611
610
  '''(INTERNAL) Get an C{obj}'s attribute by C{name}.
612
611
  '''
613
612
  if len(name_default) == 1:
@@ -616,6 +615,34 @@ def _xattr(obj, **name_default): # see .strerprs._xattrs
616
615
  raise _xAssertionError(_xattr, obj, **name_default)
617
616
 
618
617
 
618
+ def _xattrs(inst, other, *attrs): # see .errors._xattr
619
+ '''(INTERNAL) Copy attribute values from B{C{other}} to B{C{inst}}.
620
+
621
+ @arg inst: Object to copy attribute values to (any C{type}).
622
+ @arg other: Object to copy attribute values from (any C{type}).
623
+ @arg attrs: One or more attribute names (C{str}s).
624
+
625
+ @return: Object B{C{inst}}, updated.
626
+
627
+ @raise AttributeError: An B{C{attrs}} doesn't exist or isn't settable.
628
+ '''
629
+ def _getattr(o, a):
630
+ if hasattr(o, a):
631
+ return getattr(o, a)
632
+ try:
633
+ n = o._DOT_(a)
634
+ except AttributeError:
635
+ n = _streprs.Fmt.DOT(a)
636
+ raise _AttributeError(o, name=n)
637
+
638
+ for a in attrs:
639
+ s = _getattr(other, a)
640
+ g = _getattr(inst, a)
641
+ if (g is None and s is not None) or g != s:
642
+ setattr(inst, a, s) # not settable?
643
+ return inst
644
+
645
+
619
646
  def _xcallable(**names_callables):
620
647
  '''(INTERNAL) Check one or more C{callable}s.
621
648
  '''
@@ -651,9 +678,9 @@ def _xellipsoidal(**name_value): # see _xellipsoidall elel
651
678
  raise _xAssertionError(_xellipsoidal, name_value)
652
679
 
653
680
 
654
- def _xellipsoidall(point): # see _xellipsoidal
681
+ def _xellipsoidall(point): # ... elel, see _xellipsoidal
655
682
  '''(INTERNAL) Check an ellipsoidal C{point}, return C{True}
656
- if geodetic latlon or C{False} if cartesian.
683
+ if geodetic latlon, C{False} if cartesian or TypeError.
657
684
  '''
658
685
  m = _MODS.ellipsoidalBase
659
686
  ll = isinstance(point, m.LatLonEllipsoidalBase)
@@ -664,6 +691,14 @@ def _xellipsoidall(point): # see _xellipsoidal
664
691
  return ll
665
692
 
666
693
 
694
+ def _xellipsoids(E1, E2, Error=_ValueError): # see .ellipsoidalBase
695
+ '''(INTERNAL) Check ellipsoid mis-match, E2 vs E1.
696
+ '''
697
+ if E2 != E1:
698
+ raise Error(E2.named2, txt=_incompatible(E1.named2))
699
+ return E1
700
+
701
+
667
702
  def _XError(Error, *args, **kwds):
668
703
  '''(INTERNAL) Format an C{Error} or C{_Error}.
669
704
  '''
@@ -711,6 +746,15 @@ _XErrors = (_AssertionError, _AttributeError, # some isError's
711
746
  # _X2Error = {AssertionError: _AssertionError, ...
712
747
  # ZeroDivisionError: _ZeroDivisionError}
713
748
 
749
+
750
+ def _xgeodesics(G1, G2, Error=_ValueError): # see .geodesici
751
+ '''(INTERNAL) Check geodesics mis-match.
752
+ '''
753
+ if G1.ellipsoid != G2.ellipsoid:
754
+ raise Error(G1.named2, txt=_incompatible(G2.named2))
755
+ return G1
756
+
757
+
714
758
  try:
715
759
  _ = {}.__or__ # {} | {} # Python 3.9+
716
760
 
@@ -783,6 +827,15 @@ def _xkwds_item2(kwds):
783
827
  raise _xAssertionError(_xkwds_item2, kwds)
784
828
 
785
829
 
830
+ def _xkwds_kwds(kwds, **names_defaults):
831
+ '''(INTERNAL) Return a C{dict} of C{named_defaults} items replaced with C{kwds}.
832
+ '''
833
+ if not isinstance(kwds, dict):
834
+ raise _xAssertionError(_xkwds_get_, kwds)
835
+ _g = kwds.get
836
+ return dict((n, _g(n, v)) for n, v in names_defaults.items())
837
+
838
+
786
839
  def _xkwds_not(*args, **kwds):
787
840
  '''(INTERNAL) Return C{kwds} with a value not in C{args}.
788
841
  '''
@@ -811,6 +864,14 @@ def _Xorder(_Coeffs, Error, **Xorder): # in .auxLat, .ktm, .rhumb.bases, .rhumb
811
864
  t = sorted(map(str, _Coeffs.keys()))
812
865
  raise Error(X, m, txt_not_=_or(*t))
813
866
 
867
+
868
+ def _xStrError(*Refs, **name_value_Error): # in .gars, .geohash, .wgrs
869
+ '''(INTERNAL) Create a C{TypeError} for C{Garef}, C{Geohash}, C{Wgrs}.
870
+ '''
871
+ S = _MODS.unitsBase.Str
872
+ r = tuple(r.__name__ for r in Refs) + (S.__name__, _LatLon_, 'LatLon*Tuple')
873
+ return _IsnotError(*r, **name_value_Error)
874
+
814
875
  # **) MIT License
815
876
  #
816
877
  # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
pygeodesy/etm.py CHANGED
@@ -92,7 +92,7 @@ from pygeodesy.utm import _cmlon, _LLEB, _parseUTM5, _toBand, _toXtm8, \
92
92
  from math import asinh, atan2, degrees, radians, sinh, sqrt
93
93
 
94
94
  __all__ = _ALL_LAZY.etm
95
- __version__ = '24.05.31'
95
+ __version__ = '24.06.11'
96
96
 
97
97
  _OVERFLOW = _1_EPS**2 # about 2e+31
98
98
  _TAYTOL = pow(EPS, 0.6)
@@ -176,18 +176,15 @@ class Etm(Utm):
176
176
  def toLatLon(self, LatLon=None, unfalse=True, **unused): # PYCHOK expected
177
177
  '''Convert this ETM coordinate to an (ellipsoidal) geodetic point.
178
178
 
179
- @kwarg LatLon: Optional, ellipsoidal class to return the geodetic
180
- point (C{LatLon}) or C{None}.
181
- @kwarg unfalse: Unfalse B{C{easting}} and B{C{northing}} if
182
- C{falsed} (C{bool}).
179
+ @kwarg LatLon: Optional, ellipsoidal class to return the geodetic point
180
+ (C{LatLon}) or C{None}.
181
+ @kwarg unfalse: Unfalse B{C{easting}} and B{C{northing}} if C{falsed} (C{bool}).
183
182
 
184
- @return: This ETM coordinate as (B{C{LatLon}}) or a
185
- L{LatLonDatum5Tuple}C{(lat, lon, datum, gamma,
186
- scale)} if B{C{LatLon}} is C{None}.
183
+ @return: This ETM coordinate as (B{C{LatLon}}) or if C{B{LatLon} is None},
184
+ a L{LatLonDatum5Tuple}C{(lat, lon, datum, gamma, scale)}.
187
185
 
188
- @raise ETMError: This ETM coordinate's C{exacTM} and this C{datum}
189
- incompatible or no convergence transforming to
190
- lat- and longitude.
186
+ @raise ETMError: This ETM coordinate's C{exacTM} and this C{datum} are not
187
+ compatible or no convergence transforming to lat-/longitude.
191
188
 
192
189
  @raise TypeError: Invalid or non-ellipsoidal B{C{LatLon}}.
193
190
  '''
@@ -1040,10 +1037,9 @@ def parseETM5(strUTM, datum=_WGS84, Etm=Etm, falsed=True, **name):
1040
1037
  @kwarg falsed: Both easting and northing are C{falsed} (C{bool}).
1041
1038
  @kwarg name: Optional B{C{Etm}} C{B{name}=NN} (C{str}).
1042
1039
 
1043
- @return: The UTM coordinate (B{C{Etm}}) or if B{C{Etm}} is
1044
- C{None}, a L{UtmUps5Tuple}C{(zone, hemipole, easting,
1045
- northing, band)}. The C{hemipole} is the hemisphere
1046
- C{'N'|'S'}.
1040
+ @return: The UTM coordinate (B{C{Etm}}) or if C{B{Etm} is None}, a
1041
+ L{UtmUps5Tuple}C{(zone, hemipole, easting, northing, band)}
1042
+ with C{hemipole} is the hemisphere C{'N'|'S'}.
1047
1043
 
1048
1044
  @raise ETMError: Invalid B{C{strUTM}}.
1049
1045
 
@@ -1057,44 +1053,36 @@ def toEtm8(latlon, lon=None, datum=None, Etm=Etm, falsed=True,
1057
1053
  strict=True, zone=None, **name_cmoff):
1058
1054
  '''Convert a geodetic lat-/longitude to an ETM coordinate.
1059
1055
 
1060
- @arg latlon: Latitude (C{degrees}) or an (ellipsoidal)
1061
- geodetic C{LatLon} instance.
1062
- @kwarg lon: Optional longitude (C{degrees}), required
1063
- if B{C{latlon}} is in C{degrees}.
1064
- @kwarg datum: Optional datum for the ETM coordinate,
1065
- overriding B{C{latlon}}'s datum (L{Datum},
1066
- L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}).
1067
- @kwarg Etm: Optional class to return the ETM coordinate
1068
- (L{Etm}) or C{None}.
1056
+ @arg latlon: Latitude (C{degrees}) or an (ellipsoidal) geodetic
1057
+ C{LatLon} instance.
1058
+ @kwarg lon: Optional longitude (C{degrees}), required if B{C{latlon}}
1059
+ is C{degrees}, ignored otherwise.
1060
+ @kwarg datum: Optional datum for the ETM coordinate, overriding
1061
+ B{C{latlon}}'s datum (L{Datum}, L{Ellipsoid},
1062
+ L{Ellipsoid2} or L{a_f2Tuple}).
1063
+ @kwarg Etm: Optional class to return the ETM coordinate (L{Etm}) or C{None}.
1069
1064
  @kwarg falsed: False both easting and northing (C{bool}).
1070
1065
  @kwarg strict: Restrict B{C{lat}} to UTM ranges (C{bool}).
1071
1066
  @kwarg zone: Optional UTM zone to enforce (C{int} or C{str}).
1072
- @kwarg name_cmoff: Optional B{C{Etm}} C{B{name}=NN} (C{str})
1073
- and DEPRECATED keyword argument C{B{cmoff}=True}
1074
- to offset the longitude from the zone's central
1075
- meridian (C{bool}), use B{C{falsed}} instead.
1067
+ @kwarg name_cmoff: Optional B{C{Etm}} C{B{name}=NN} (C{str}) and DEPRECATED
1068
+ keyword argument C{B{cmoff}=True} to offset the longitude from
1069
+ the zone's central meridian (C{bool}), use B{C{falsed}} instead.
1076
1070
 
1077
- @return: The ETM coordinate as an B{C{Etm}} instance or a
1078
- L{UtmUps8Tuple}C{(zone, hemipole, easting, northing,
1079
- band, datum, gamma, scale)} if B{C{Etm}} is C{None}
1080
- or not B{C{falsed}}. The C{hemipole} is the C{'N'|'S'}
1081
- hemisphere.
1071
+ @return: The ETM coordinate as B{C{Etm}} or if C{B{Etm} is None} or not B{C{falsed}},
1072
+ a L{UtmUps8Tuple}C{(zone, hemipole, easting, northing, band, datum, gamma,
1073
+ scale)}. The C{hemipole} is the C{'N'|'S'} hemisphere.
1082
1074
 
1083
- @raise ETMError: No convergence transforming to ETM easting
1084
- and northing.
1075
+ @raise ETMError: No convergence transforming to ETM easting and northing.
1085
1076
 
1086
- @raise ETMError: Invalid B{C{zone}} or near-spherical or
1087
- incompatible B{C{datum}} or C{ellipsoid}.
1077
+ @raise ETMError: Invalid B{C{zone}} or near-spherical or incompatible B{C{datum}}
1078
+ or C{ellipsoid}.
1088
1079
 
1089
- @raise RangeError: If B{C{lat}} outside the valid UTM bands or
1090
- if B{C{lat}} or B{C{lon}} outside the valid
1091
- range and L{pygeodesy.rangerrors} set to C{True}.
1080
+ @raise RangeError: If B{C{lat}} outside the valid UTM bands or if B{C{lat}} or B{C{lon}}
1081
+ outside the valid range and L{rangerrors<pygeodesy.rangerrors>} is C{True}.
1092
1082
 
1093
- @raise TypeError: Invalid or near-spherical B{C{datum}} or
1094
- B{C{latlon}} not ellipsoidal.
1083
+ @raise TypeError: Invalid or near-spherical B{C{datum}} or B{C{latlon}} not ellipsoidal.
1095
1084
 
1096
- @raise ValueError: The B{C{lon}} value is missing or B{C{latlon}}
1097
- is invalid.
1085
+ @raise ValueError: The B{C{lon}} value is missing or B{C{latlon}} is invalid.
1098
1086
  '''
1099
1087
  z, B, lat, lon, d, f, n = _to7zBlldfn(latlon, lon, datum,
1100
1088
  falsed, zone, strict,
pygeodesy/formy.py CHANGED
@@ -29,7 +29,7 @@ from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
29
29
  # from pygeodesy.streprs import Fmt, unstr # from .fsums
30
30
  # from pygeodesy.triaxials import _hartzell3 # _MODS
31
31
  from pygeodesy.units import _isHeight, _isRadius, Bearing, Degrees_, Distance, \
32
- Distance_, Height, Lam_, Lat, Lon, Meter_, Phi_, \
32
+ Distance_, Height, Lamd, Lat, Lon, Meter_, Phid, \
33
33
  Radians, Radians_, Radius, Radius_, Scalar, _100km
34
34
  from pygeodesy.utily import acos1, atan2b, atan2d, degrees2m, _loneg, m2degrees, \
35
35
  tan_2, sincos2, sincos2_, sincos2d_, _Wrap
@@ -42,7 +42,7 @@ from contextlib import contextmanager
42
42
  from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
43
43
 
44
44
  __all__ = _ALL_LAZY.formy
45
- __version__ = '24.05.28'
45
+ __version__ = '24.06.15'
46
46
 
47
47
  _RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
48
48
  _ratio_ = 'ratio'
@@ -62,8 +62,8 @@ def _anti2(a, b, n_2, n, n2):
62
62
 
63
63
 
64
64
  def antipode(lat, lon, **name):
65
- '''Return the antipode, the point diametrically opposite
66
- to a given point in C{degrees}.
65
+ '''Return the antipode, the point diametrically opposite to a given
66
+ point in C{degrees}.
67
67
 
68
68
  @arg lat: Latitude (C{degrees}).
69
69
  @arg lon: Longitude (C{degrees}).
@@ -78,8 +78,8 @@ def antipode(lat, lon, **name):
78
78
 
79
79
 
80
80
  def antipode_(phi, lam, **name):
81
- '''Return the antipode, the point diametrically opposite
82
- to a given point in C{radians}.
81
+ '''Return the antipode, the point diametrically opposite to a given
82
+ point in C{radians}.
83
83
 
84
84
  @arg phi: Latitude (C{radians}).
85
85
  @arg lam: Longitude (C{radians}).
@@ -94,8 +94,8 @@ def antipode_(phi, lam, **name):
94
94
 
95
95
 
96
96
  def bearing(lat1, lon1, lat2, lon2, **final_wrap):
97
- '''Compute the initial or final bearing (forward or reverse
98
- azimuth) between a (spherical) start and end point.
97
+ '''Compute the initial or final bearing (forward or reverse azimuth)
98
+ between two (spherical) points.
99
99
 
100
100
  @arg lat1: Start latitude (C{degrees}).
101
101
  @arg lon1: Start longitude (C{degrees}).
@@ -104,33 +104,33 @@ def bearing(lat1, lon1, lat2, lon2, **final_wrap):
104
104
  @kwarg final_wrap: Optional keyword arguments for function
105
105
  L{pygeodesy.bearing_}.
106
106
 
107
- @return: Initial or final bearing (compass C{degrees360}) or
108
- zero if start and end point coincide.
107
+ @return: Initial or final bearing (compass C{degrees360}) or zero if
108
+ both points coincide.
109
109
  '''
110
- r = bearing_(Phi_(lat1=lat1), Lam_(lon1=lon1),
111
- Phi_(lat2=lat2), Lam_(lon2=lon2), **final_wrap)
110
+ r = bearing_(Phid(lat1=lat1), Lamd(lon1=lon1),
111
+ Phid(lat2=lat2), Lamd(lon2=lon2), **final_wrap)
112
112
  return degrees(r)
113
113
 
114
114
 
115
115
  def bearing_(phi1, lam1, phi2, lam2, final=False, wrap=False):
116
- '''Compute the initial or final bearing (forward or reverse azimuth)
117
- between a (spherical) start and end point.
116
+ '''Compute the initial or final bearing (forward or reverse azimuth) between
117
+ two (spherical) points.
118
118
 
119
119
  @arg phi1: Start latitude (C{radians}).
120
120
  @arg lam1: Start longitude (C{radians}).
121
121
  @arg phi2: End latitude (C{radians}).
122
122
  @arg lam2: End longitude (C{radians}).
123
- @kwarg final: If C{True}, return the final, otherwise the initial
124
- bearing (C{bool}).
125
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}}
126
- and B{C{lam2}} (C{bool}).
123
+ @kwarg final: If C{True}, return the final, otherwise the initial bearing
124
+ (C{bool}).
125
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}} and
126
+ B{C{lam2}} (C{bool}).
127
127
 
128
- @return: Initial or final bearing (compass C{radiansPI2}) or zero if
129
- start and end point coincide.
128
+ @return: Initial or final bearing (compass C{radiansPI2}) or zero if both
129
+ are coincident.
130
130
 
131
- @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>},
132
- U{Course between two points<https://www.EdWilliams.org/avform147.htm#Crs>}
133
- and U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
131
+ @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>}, U{Course
132
+ between two points<https://www.EdWilliams.org/avform147.htm#Crs>} and
133
+ U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
134
134
  https://MathForum.org/library/drmath/view/55417.html>}.
135
135
  '''
136
136
  db, phi2, lam2 = _Wrap.philam3(lam1, phi2, lam2, wrap)
@@ -198,13 +198,13 @@ def cosineAndoyerLambert(lat1, lon1, lat2, lon2, datum=_WGS84, wrap=False):
198
198
  @arg lon1: Start longitude (C{degrees}).
199
199
  @arg lat2: End latitude (C{degrees}).
200
200
  @arg lon2: End longitude (C{degrees}).
201
- @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid},
202
- L{Ellipsoid2} or L{a_f2Tuple}) to use.
203
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll
204
- B{C{lat2}} and B{C{lon2}} (C{bool}).
201
+ @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid}, L{Ellipsoid2} or
202
+ L{a_f2Tuple}) to use.
203
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and
204
+ B{C{lon2}} (C{bool}).
205
205
 
206
- @return: Distance (C{meter}, same units as the B{C{datum}}'s
207
- ellipsoid axes or C{radians} if B{C{datum}} is C{None}).
206
+ @return: Distance (C{meter}, same units as the B{C{datum}}'s ellipsoid axes or
207
+ C{radians} if C{B{datum} is None}).
208
208
 
209
209
  @raise TypeError: Invalid B{C{datum}}.
210
210
 
@@ -224,8 +224,8 @@ def cosineAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
224
224
  @arg phi2: End latitude (C{radians}).
225
225
  @arg phi1: Start latitude (C{radians}).
226
226
  @arg lam21: Longitudinal delta, M{end-start} (C{radians}).
227
- @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid},
228
- L{Ellipsoid2} or L{a_f2Tuple}) to use.
227
+ @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid}, L{Ellipsoid2} or
228
+ L{a_f2Tuple}) to use.
229
229
 
230
230
  @return: Angular distance (C{radians}).
231
231
 
@@ -263,13 +263,13 @@ def cosineForsytheAndoyerLambert(lat1, lon1, lat2, lon2, datum=_WGS84, wrap=Fals
263
263
  @arg lon1: Start longitude (C{degrees}).
264
264
  @arg lat2: End latitude (C{degrees}).
265
265
  @arg lon2: End longitude (C{degrees}).
266
- @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid},
267
- L{Ellipsoid2} or L{a_f2Tuple}) to use.
268
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll
269
- B{C{lat2}} and B{C{lon2}} (C{bool}).
266
+ @kwarg datum: Datum (L{Datum}) or ellipsoid (L{Ellipsoid}, L{Ellipsoid2} or
267
+ L{a_f2Tuple}) to use.
268
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and
269
+ B{C{lon2}} (C{bool}).
270
270
 
271
- @return: Distance (C{meter}, same units as the B{C{datum}}'s
272
- ellipsoid axes or C{radians} if B{C{datum}} is C{None}).
271
+ @return: Distance (C{meter}, same units as the B{C{datum}}'s ellipsoid axes or
272
+ C{radians} if C{B{datum} is None}).
273
273
 
274
274
  @raise TypeError: Invalid B{C{datum}}.
275
275
 
@@ -380,9 +380,9 @@ def _d3(wrap, lat1, lon1, lat2, lon2):
380
380
  '''
381
381
  if wrap:
382
382
  d_lon, lat2, _ = _Wrap.latlon3(lon1, lat2, lon2, wrap)
383
- return radians(lat2), Phi_(lat1=lat1), radians(d_lon)
383
+ return radians(lat2), Phid(lat1=lat1), radians(d_lon)
384
384
  else: # for backward compaibility
385
- return Phi_(lat2=lat2), Phi_(lat1=lat1), Phi_(d_lon=lon2 - lon1)
385
+ return Phid(lat2=lat2), Phid(lat1=lat1), Phid(d_lon=lon2 - lon1)
386
386
 
387
387
 
388
388
  def _dE(func_, earth, *wrap_lls):
@@ -458,34 +458,31 @@ def equirectangular4(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
458
458
  '''Compute the distance between two points using the U{Equirectangular Approximation
459
459
  / Projection<https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}.
460
460
 
461
- This approximation is valid for short distance of several hundred Km
462
- or Miles, see the B{C{limit}} keyword argument and L{LimitError}.
461
+ This approximation is valid for short distance of several hundred Km or Miles, see
462
+ the B{C{limit}} keyword argument and L{LimitError}.
463
463
 
464
464
  @arg lat1: Start latitude (C{degrees}).
465
465
  @arg lon1: Start longitude (C{degrees}).
466
466
  @arg lat2: End latitude (C{degrees}).
467
467
  @arg lon2: End longitude (C{degrees}).
468
- @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine
469
- of the mean latitude (C{bool}).
470
- @kwarg limit: Optional limit for lat- and longitudinal deltas (C{degrees}) or
471
- C{None} or C{0} for unlimited.
472
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and
473
- B{C{lon2}} (C{bool}).
468
+ @kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine of the mean
469
+ latitude (C{bool}).
470
+ @kwarg limit: Optional limit for lat- and longitudinal deltas (C{degrees}) or C{None}
471
+ or C{0} for unlimited.
472
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and B{C{lon2}}
473
+ (C{bool}).
474
474
 
475
475
  @return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon, unroll_lon2)}
476
476
  in C{degrees squared}.
477
477
 
478
- @raise LimitError: If the lat- and/or longitudinal delta exceeds the
479
- B{C{-limit..limit}} range and L{pygeodesy.limiterrors}
480
- set to C{True}.
478
+ @raise LimitError: If the lat- and/or longitudinal delta exceeds the B{C{-limit..limit}}
479
+ range and L{limiterrors<pygeodesy.limiterrors>} is C{True}.
481
480
 
482
- @see: U{Local, flat earth approximation
483
- <https://www.EdWilliams.org/avform.htm#flat>}, functions
484
- L{equirectangular}, L{cosineAndoyerLambert},
485
- L{cosineForsytheAndoyerLambert}, L{cosineLaw}, L{euclidean},
486
- L{flatLocal}/L{hubeny}, L{flatPolar}, L{haversine}, L{thomas}
487
- and L{vincentys} and methods L{Ellipsoid.distance2},
488
- C{LatLon.distanceTo*} and C{LatLon.equirectangularTo}.
481
+ @see: U{Local, flat earth approximation<https://www.EdWilliams.org/avform.htm#flat>},
482
+ functions L{equirectangular}, L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert},
483
+ L{cosineLaw}, L{euclidean}, L{flatLocal}/L{hubeny}, L{flatPolar}, L{haversine},
484
+ L{thomas} and L{vincentys} and methods L{Ellipsoid.distance2}, C{LatLon.distanceTo*}
485
+ and C{LatLon.equirectangularTo}.
489
486
  '''
490
487
  d_lon, lat2, ulon2 = _Wrap.latlon3(lon1, lat2, lon2, wrap)
491
488
  d_lat = lat2 - lat1
@@ -1078,7 +1075,7 @@ def heightOf(angle, distance, radius=R_M):
1078
1075
 
1079
1076
  if d > EPS0: # and h > EPS0
1080
1077
  d = d / h # /= h chokes PyChecker
1081
- s = sin(Phi_(angle=angle, clip=_180_0))
1078
+ s = sin(Phid(angle=angle, clip=_180_0))
1082
1079
  s = fsumf_(_1_0, s * d * _2_0, d**2)
1083
1080
  if s > 0:
1084
1081
  return h * sqrt(s) - r