pygeodesy 24.5.15__py2.py3-none-any.whl → 24.5.24__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 (72) hide show
  1. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.5.24.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +1 -1
  4. pygeodesy/albers.py +41 -41
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/auxAngle.py +32 -31
  7. pygeodesy/auxilats/auxLat.py +80 -51
  8. pygeodesy/azimuthal.py +123 -124
  9. pygeodesy/basics.py +8 -6
  10. pygeodesy/booleans.py +11 -12
  11. pygeodesy/cartesianBase.py +25 -23
  12. pygeodesy/clipy.py +3 -3
  13. pygeodesy/css.py +50 -42
  14. pygeodesy/datums.py +42 -41
  15. pygeodesy/dms.py +6 -6
  16. pygeodesy/ecef.py +23 -24
  17. pygeodesy/ellipsoidalBase.py +28 -27
  18. pygeodesy/ellipsoidalBaseDI.py +3 -4
  19. pygeodesy/ellipsoidalNvector.py +11 -12
  20. pygeodesy/ellipsoids.py +41 -35
  21. pygeodesy/elliptic.py +3 -4
  22. pygeodesy/epsg.py +4 -3
  23. pygeodesy/errors.py +34 -12
  24. pygeodesy/etm.py +62 -54
  25. pygeodesy/fmath.py +36 -30
  26. pygeodesy/formy.py +93 -65
  27. pygeodesy/frechet.py +117 -102
  28. pygeodesy/fstats.py +21 -14
  29. pygeodesy/fsums.py +67 -57
  30. pygeodesy/gars.py +10 -9
  31. pygeodesy/geodesicw.py +19 -17
  32. pygeodesy/geodesicx/__init__.py +1 -1
  33. pygeodesy/geodesicx/gx.py +40 -32
  34. pygeodesy/geodesicx/gxarea.py +12 -9
  35. pygeodesy/geodesicx/gxbases.py +3 -4
  36. pygeodesy/geodesicx/gxline.py +6 -8
  37. pygeodesy/geodsolve.py +28 -27
  38. pygeodesy/geohash.py +47 -44
  39. pygeodesy/geoids.py +34 -32
  40. pygeodesy/hausdorff.py +112 -99
  41. pygeodesy/heights.py +134 -127
  42. pygeodesy/internals.py +14 -9
  43. pygeodesy/interns.py +3 -6
  44. pygeodesy/iters.py +19 -17
  45. pygeodesy/karney.py +15 -12
  46. pygeodesy/ktm.py +25 -18
  47. pygeodesy/latlonBase.py +12 -11
  48. pygeodesy/lazily.py +4 -4
  49. pygeodesy/lcc.py +24 -25
  50. pygeodesy/ltp.py +83 -71
  51. pygeodesy/ltpTuples.py +7 -5
  52. pygeodesy/mgrs.py +3 -3
  53. pygeodesy/named.py +126 -42
  54. pygeodesy/namedTuples.py +33 -25
  55. pygeodesy/nvectorBase.py +7 -7
  56. pygeodesy/points.py +9 -9
  57. pygeodesy/rhumb/__init__.py +1 -1
  58. pygeodesy/solveBase.py +5 -5
  59. pygeodesy/sphericalTrigonometry.py +5 -5
  60. pygeodesy/streprs.py +5 -5
  61. pygeodesy/trf.py +5 -5
  62. pygeodesy/triaxials.py +67 -63
  63. pygeodesy/units.py +35 -35
  64. pygeodesy/unitsBase.py +24 -11
  65. pygeodesy/utm.py +53 -53
  66. pygeodesy/utmupsBase.py +10 -8
  67. pygeodesy/vector2d.py +6 -7
  68. pygeodesy/vector3d.py +16 -17
  69. pygeodesy/vector3dBase.py +4 -5
  70. PyGeodesy-24.5.15.dist-info/RECORD +0 -116
  71. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
  72. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/units.py CHANGED
@@ -12,7 +12,7 @@ from pygeodesy.constants import EPS, EPS1, PI, PI2, PI_2, _umod_360, _0_0, \
12
12
  from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, \
13
13
  _toDMS, toDMS
14
14
  from pygeodesy.errors import _AssertionError, _IsnotError, TRFError, UnitError, \
15
- _xkwds, _xkwds_item2
15
+ _xkwds
16
16
  from pygeodesy.interns import NN, _band_, _bearing_, _degrees_, _degrees2_, \
17
17
  _distance_, _E_, _easting_, _epoch_, _EW_, _feet_, \
18
18
  _height_, _lam_, _lat_, _LatLon_, _lon_, _meter_, \
@@ -23,13 +23,13 @@ from pygeodesy.interns import NN, _band_, _bearing_, _degrees_, _degrees2_, \
23
23
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
24
24
  from pygeodesy.props import Property_RO
25
25
  # from pygeodesy.streprs import Fmt, fstr # from .unitsBase
26
- from pygeodesy.unitsBase import _Error, Float, Fmt, fstr, Int, _NamedUnit, \
27
- Radius, Str # PYCHOK shared .namedTuples
26
+ from pygeodesy.unitsBase import _Error, Float, Fmt, fstr, Int, _arg_name_arg2, \
27
+ _NamedUnit, Radius, Str # PYCHOK shared .namedTuples
28
28
 
29
29
  from math import degrees, radians
30
30
 
31
31
  __all__ = _ALL_LAZY.units
32
- __version__ = '24.05.10'
32
+ __version__ = '24.05.20'
33
33
 
34
34
  _negative_falsed_ = 'negative, falsed'
35
35
 
@@ -46,15 +46,15 @@ class Float_(Float):
46
46
  @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
47
47
  @kwarg low: Optional lower B{C{arg}} limit (C{float} or C{None}).
48
48
  @kwarg high: Optional upper B{C{arg}} limit (C{float} or C{None}).
49
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
50
- and B{C{arg}}.
49
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
50
+ B{C{arg}} and B{C{name}} ones.
51
51
 
52
52
  @returns: A C{Float_} instance.
53
53
 
54
54
  @raise Error: Invalid B{C{arg}} or B{C{arg}} below B{C{low}} or above B{C{high}}.
55
55
  '''
56
56
  if name_arg:
57
- name, arg = _xkwds_item2(name_arg)
57
+ name, arg = _arg_name_arg2(arg, **name_arg)
58
58
  self = Float.__new__(cls, arg=arg, name=name, Error=Error)
59
59
  if (low is not None) and self < low:
60
60
  txt = Fmt.limit(below=Fmt.g(low, prec=6, ints=isinstance(self, Epoch)))
@@ -77,15 +77,15 @@ class Int_(Int):
77
77
  @kwarg Error: Optional error to raise, overriding the default C{UnitError}.
78
78
  @kwarg low: Optional lower B{C{arg}} limit (C{int} or C{None}).
79
79
  @kwarg high: Optional upper B{C{arg}} limit (C{int} or C{None}).
80
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
81
- and B{C{arg}}.
80
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
81
+ B{C{arg}} and B{C{name}} ones.
82
82
 
83
83
  @returns: An L{Int_} instance.
84
84
 
85
85
  @raise Error: Invalid B{C{arg}} or B{C{arg}} below B{C{low}} or above B{C{high}}.
86
86
  '''
87
87
  if name_arg:
88
- name, arg = _xkwds_item2(name_arg)
88
+ name, arg = _arg_name_arg2(arg, **name_arg)
89
89
  self = Int.__new__(cls, arg=arg, name=name, Error=Error)
90
90
  if (low is not None) and self < low:
91
91
  txt = Fmt.limit(below=low)
@@ -118,7 +118,7 @@ class Bool(Int, _NamedUnit):
118
118
  @raise Error: Invalid B{C{arg}}.
119
119
  '''
120
120
  if name_arg:
121
- name, arg = _xkwds_item2(name_arg)
121
+ name, arg = _arg_name_arg2(arg, **name_arg)
122
122
  try:
123
123
  b = bool(arg)
124
124
  except Exception as x: # XXX not ... as x:
@@ -193,7 +193,7 @@ class Degrees(Float):
193
193
  range and L{pygeodesy.rangerrors} set to C{True}.
194
194
  '''
195
195
  if name_arg:
196
- name, arg = _xkwds_item2(name_arg)
196
+ name, arg = _arg_name_arg2(arg, **name_arg)
197
197
  try:
198
198
  d = Float.__new__(cls, parseDMS(arg, suffix=suffix, clip=clip),
199
199
  Error=Error, name=name)
@@ -253,15 +253,15 @@ class Degrees_(Degrees):
253
253
  @kwarg suffix: Optional, valid compass direction suffixes (C{NSEW}).
254
254
  @kwarg low: Optional lower B{C{arg}} limit (C{float} or C{None}).
255
255
  @kwarg high: Optional upper B{C{arg}} limit (C{float} or C{None}).
256
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
257
- and B{C{arg}}.
256
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
257
+ B{C{arg}} and B{C{name}} ones.
258
258
 
259
259
  @returns: A C{Degrees} instance.
260
260
 
261
261
  @raise Error: Invalid B{C{arg}} or B{C{arg}} below B{C{low}} or above B{C{high}}.
262
262
  '''
263
263
  if name_arg:
264
- name, arg = _xkwds_item2(name_arg)
264
+ name, arg = _arg_name_arg2(arg, **name_arg)
265
265
  self = Degrees.__new__(cls, arg=arg, name=name, Error=Error, suffix=suffix, clip=0)
266
266
  if (low is not None) and self < low:
267
267
  txt = Fmt.limit(below=low)
@@ -295,8 +295,8 @@ class Radians(Float):
295
295
  @kwarg suffix: Optional, valid compass direction suffixes (C{NSEW}).
296
296
  @kwarg clip: Optional B{C{arg}} range B{C{-clip..+clip}} (C{radians} or C{0}
297
297
  or C{None} for unclipped).
298
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
299
- and B{C{arg}}.
298
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
299
+ B{C{arg}} and B{C{name}} ones.
300
300
 
301
301
  @returns: A C{Radians} instance.
302
302
 
@@ -304,7 +304,7 @@ class Radians(Float):
304
304
  range and L{pygeodesy.rangerrors} set to C{True}.
305
305
  '''
306
306
  if name_arg:
307
- name, arg = _xkwds_item2(name_arg)
307
+ name, arg = _arg_name_arg2(arg, **name_arg)
308
308
  try:
309
309
  return Float.__new__(cls, parseRad(arg, suffix=suffix, clip=clip),
310
310
  Error=Error, name=name)
@@ -324,8 +324,8 @@ class Radians(Float):
324
324
  def toRepr(self, std=False, **prec_fmt_ints): # PYCHOK prec=8, ...
325
325
  '''Return a representation of this C{Radians}.
326
326
 
327
- @kwarg std: If C{True} return the standard C{repr},
328
- otherwise the named representation (C{bool}).
327
+ @kwarg std: If C{True} return the standard C{repr}, otherwise
328
+ the named representation (C{bool}).
329
329
 
330
330
  @see: Methods L{Radians.toStr}, L{Float.toRepr} and function
331
331
  L{pygeodesy.toDMS} for more documentation.
@@ -354,15 +354,15 @@ class Radians_(Radians):
354
354
  @kwarg suffix: Optional, valid compass direction suffixes (C{NSEW}).
355
355
  @kwarg low: Optional lower B{C{arg}} limit (C{float} or C{None}).
356
356
  @kwarg high: Optional upper B{C{arg}} limit (C{float} or C{None}).
357
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
358
- and B{C{arg}}.
357
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
358
+ B{C{arg}} and B{C{name}} ones.
359
359
 
360
360
  @returns: A C{Radians_} instance.
361
361
 
362
362
  @raise Error: Invalid B{C{arg}} or B{C{arg}} below B{C{low}} or above B{C{high}}.
363
363
  '''
364
364
  if name_arg:
365
- name, arg = _xkwds_item2(name_arg)
365
+ name, arg = _arg_name_arg2(arg, **name_arg)
366
366
  self = Radians.__new__(cls, arg=arg, name=name, Error=Error, suffix=suffix, clip=0)
367
367
  if (low is not None) and self < low:
368
368
  txt = Fmt.limit(below=low)
@@ -392,7 +392,7 @@ class Bearing(Degrees):
392
392
  '''New L{Bearing} instance, see L{Degrees}.
393
393
  '''
394
394
  if name_arg:
395
- name, arg = _xkwds_item2(name_arg)
395
+ name, arg = _arg_name_arg2(arg, **name_arg)
396
396
  d = Degrees.__new__(cls, arg=arg, name=name, Error=Error, suffix=_N_, clip=clip)
397
397
  b = _umod_360(d) # 0 <= b < 360
398
398
  return d if b == d else Degrees.__new__(cls, arg=b, name=name, Error=Error)
@@ -438,15 +438,15 @@ class Easting(Float):
438
438
  @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
439
439
  @kwarg falsed: The B{C{arg}} value includes false origin (C{bool}).
440
440
  @kwarg high: Optional upper B{C{arg}} easting limit (C{scalar} or C{None}).
441
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
442
- and B{C{arg}}.
441
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
442
+ B{C{arg}} and B{C{name}} ones.
443
443
 
444
444
  @returns: An C{Easting} instance.
445
445
 
446
446
  @raise Error: Invalid B{C{arg}}, above B{C{high}} or negative, falsed B{C{arg}}.
447
447
  '''
448
448
  if name_arg:
449
- name, arg = _xkwds_item2(name_arg)
449
+ name, arg = _arg_name_arg2(arg, **name_arg)
450
450
  self = Float.__new__(cls, arg=arg, name=name, Error=Error)
451
451
  if high and (self < 0 or self > high): # like Veness
452
452
  raise _Error(cls, arg, name, Error)
@@ -465,7 +465,7 @@ class Epoch(Float_): # in .ellipsoidalBase, .trf
465
465
  '''New L{Epoch} instance, see L{Float_}.
466
466
  '''
467
467
  if name_arg:
468
- name, arg = _xkwds_item2(name_arg)
468
+ name, arg = _arg_name_arg2(arg, **name_arg)
469
469
  return arg if isinstance(arg, Epoch) else Float_.__new__(cls,
470
470
  arg=arg, name=name, Error=Error, low=low, high=high)
471
471
 
@@ -513,8 +513,8 @@ class FIx(Float_):
513
513
  @arg fi: The fractional index (C{float} or C{int}).
514
514
  @kwarg fin: Optional C{len}, the number of C{points}, the index
515
515
  C{[n]} wrapped to C{[0]} (C{int} or C{None}).
516
- @kwarg name_Error: Optional keyword argument C{B{name}=NN}
517
- and C{B{Error}=UnitError}.
516
+ @kwarg name_Error: Optional C{B{name}=NN} (C{str}) and keyword
517
+ argument C{B{Error}=UnitError}.
518
518
 
519
519
  @return: The B{C{fi}} (named L{FIx}).
520
520
 
@@ -629,7 +629,7 @@ class Lam_(Lam):
629
629
  '''New L{Lam_} instance, see L{Lam} and L{Radians}.
630
630
  '''
631
631
  if name_arg:
632
- name, arg = _xkwds_item2(name_arg)
632
+ name, arg = _arg_name_arg2(arg, **name_arg)
633
633
  d = Lam.__new__(cls, arg=arg, name=name, Error=Error, clip=clip)
634
634
  return Radians.__new__(cls, radians(d), name=name, Error=Error)
635
635
 
@@ -750,15 +750,15 @@ class Northing(Float):
750
750
  @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
751
751
  @kwarg falsed: The B{C{arg}} value includes false origin (C{bool}).
752
752
  @kwarg high: Optional upper B{C{arg}} northing limit (C{scalar} or C{None}).
753
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of B{C{name}}
754
- and B{C{arg}}.
753
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
754
+ B{C{arg}} and B{C{name}} ones.
755
755
 
756
756
  @returns: A C{Northing} instance.
757
757
 
758
758
  @raise Error: Invalid B{C{arg}}, above B{C{high}} or negative, falsed B{C{arg}}.
759
759
  '''
760
760
  if name_arg:
761
- name, arg = _xkwds_item2(name_arg)
761
+ name, arg = _arg_name_arg2(arg, **name_arg)
762
762
  self = Float.__new__(cls, arg=arg, name=name, Error=Error)
763
763
  if high and (self < 0 or self > high):
764
764
  raise _Error(cls, arg, name, Error)
@@ -792,7 +792,7 @@ class Phi_(Phi):
792
792
  '''New L{Phi_} instance, see L{Phi} and L{Radians}.
793
793
  '''
794
794
  if name_arg:
795
- name, arg = _xkwds_item2(name_arg)
795
+ name, arg = _arg_name_arg2(arg, **name_arg)
796
796
  d = Phi.__new__(cls, arg=arg, name=name, Error=Error, clip=clip)
797
797
  return Radians.__new__(cls, arg=radians(d), name=name, Error=Error)
798
798
 
pygeodesy/unitsBase.py CHANGED
@@ -4,9 +4,9 @@
4
4
  u'''Basic C{Float}, C{Int} and C{Str}ing units classes.
5
5
  '''
6
6
 
7
- from pygeodesy.errors import UnitError, _XError, _xkwds_item2
7
+ from pygeodesy.errors import _UnexpectedError, UnitError, _XError
8
8
  from pygeodesy.interns import NN, _degrees_, _degrees2_, _invalid_, \
9
- _meter_, _radians_, _radians2_, \
9
+ _meter_, MISSING, _radians_, _radians2_, \
10
10
  _radius_, _UNDER_, _std_ # PYCHOK used!
11
11
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
12
12
  from pygeodesy.named import modulename, _Named, property_doc_
@@ -14,7 +14,7 @@ from pygeodesy.named import modulename, _Named, property_doc_
14
14
  from pygeodesy.streprs import Fmt, fstr
15
15
 
16
16
  __all__ = _ALL_LAZY.unitsBase
17
- __version__ = '24.02.20'
17
+ __version__ = '24.05.20'
18
18
 
19
19
 
20
20
  class _NamedUnit(_Named):
@@ -69,14 +69,14 @@ class Float(float, _NamedUnit):
69
69
  @kwarg Error: Optional error to raise, overriding the default
70
70
  L{UnitError}.
71
71
  @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu
72
- of B{C{name}} and B{C{arg}}.
72
+ of separate B{C{arg}} and B{C{name}} ones.
73
73
 
74
74
  @returns: A C{Float} instance.
75
75
 
76
76
  @raise Error: Invalid B{C{arg}}.
77
77
  '''
78
78
  if name_arg:
79
- name, arg = _xkwds_item2(name_arg)
79
+ name, arg = _arg_name_arg2(arg, **name_arg)
80
80
  try:
81
81
  self = float.__new__(cls, arg)
82
82
  if name:
@@ -146,15 +146,15 @@ class Int(int, _NamedUnit):
146
146
  @kwarg name: Optional instance name (C{str}).
147
147
  @kwarg Error: Optional error to raise, overriding the
148
148
  default L{UnitError}.
149
- @kwarg name_arg: Optional C{name=arg} keyword argument,
150
- inlieu of B{C{name}} and B{C{arg}}.
149
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu
150
+ of separate B{C{arg}} and B{C{name}} ones.
151
151
 
152
152
  @returns: An C{Int} instance.
153
153
 
154
154
  @raise Error: Invalid B{C{arg}}.
155
155
  '''
156
156
  if name_arg:
157
- name, arg = _xkwds_item2(name_arg)
157
+ name, arg = _arg_name_arg2(arg, **name_arg)
158
158
  try:
159
159
  self = int.__new__(cls, arg)
160
160
  if name:
@@ -223,8 +223,8 @@ class Str(str, _NamedUnit):
223
223
  @kwarg name: Optional instance name (C{str}).
224
224
  @kwarg Error: Optional error to raise, overriding the
225
225
  default (C{ValueError}).
226
- @kwarg name_arg: Optional C{name=arg} keyword argument,
227
- inlieu of B{C{name}} and B{C{arg}}.
226
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu
227
+ of separate B{C{arg}} and B{C{name}} ones.
228
228
 
229
229
  @returns: A L{Str} instance.
230
230
 
@@ -233,7 +233,7 @@ class Str(str, _NamedUnit):
233
233
  @see: Callable, not-nameable class L{pygeodesy.Str_}.
234
234
  '''
235
235
  if name_arg:
236
- name, arg = _xkwds_item2(name_arg)
236
+ name, arg = _arg_name_arg2(arg, **name_arg)
237
237
  try:
238
238
  self = str.__new__(cls, arg)
239
239
  if name:
@@ -324,6 +324,19 @@ def _Error(clas, arg, name, Error, txt=_invalid_, x=None):
324
324
  return _XError(Error, n, arg, txt=txt, cause=x)
325
325
 
326
326
 
327
+ def _arg_name_arg2(arg, name__=None, **name_arg): # in .units
328
+ '''(INTERNAL) Get the 2-tuple C{(name, arg)}.
329
+ '''
330
+ if name__ is None:
331
+ t = name_arg.popitem() if len(name_arg) == 1 else \
332
+ (MISSING, arg)
333
+ else:
334
+ t = name__.__name__, arg
335
+ if name_arg:
336
+ raise _UnexpectedError(**name_arg)
337
+ return t
338
+
339
+
327
340
  __all__ += _ALL_DOCS(_NamedUnit)
328
341
 
329
342
  # **) MIT License
pygeodesy/utm.py CHANGED
@@ -35,17 +35,17 @@ and Henrik Seidel U{'Die Mathematik der Gauß-Krueger-Abbildung'
35
35
 
36
36
  from pygeodesy.basics import len2, map2, neg # splice
37
37
  from pygeodesy.constants import EPS, EPS0, _K0_UTM, _0_0, _0_0001
38
- from pygeodesy.datums import _ellipsoidal_datum, _WGS84
38
+ from pygeodesy.datums import _ellipsoidal_datum, _WGS84, _under
39
39
  from pygeodesy.dms import degDMS, parseDMS2
40
40
  from pygeodesy.errors import MGRSError, RangeError, _ValueError, \
41
- _xkwds_get
41
+ _xkwds_get, _xkwds_pop2
42
42
  from pygeodesy.fmath import fdot3, hypot, hypot1, _operator
43
- # from pygeodesy.internals import _under # from .utmupsBase
43
+ # from pygeodesy.internals import _under # from .datums
44
44
  from pygeodesy.interns import MISSING, NN, _by_, _COMMASPACE_, _N_, \
45
45
  _NS_, _outside_, _range_, _S_, _scale0_, \
46
46
  _SPACE_, _UTM_, _V_, _X_, _zone_
47
- from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
48
- # from pygeodesy.named import _xnamed # from .utmupsBase
47
+ # from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
48
+ from pygeodesy.named import _name__, _name2__, _ALL_LAZY, _MODS
49
49
  from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple, \
50
50
  UtmUps8Tuple, UtmUpsLatLon5Tuple
51
51
  from pygeodesy.props import deprecated_method, property_doc_, \
@@ -55,8 +55,8 @@ from pygeodesy.units import Band, Int, Lat, Lon, Meter, Zone
55
55
  from pygeodesy.utily import atan1, degrees90, degrees180, sincos2
56
56
  from pygeodesy.utmupsBase import _hemi, _LLEB, _parseUTMUPS5, _to4lldn, \
57
57
  _to3zBhp, _to3zll, _UPS_LATS, _UPS_ZONE, \
58
- _UTM_LAT_MAX, _UTM_ZONE_MAX, _under, \
59
- _UTM_LAT_MIN, _UTM_ZONE_MIN, _xnamed, \
58
+ _UTM_LAT_MAX, _UTM_ZONE_MAX, \
59
+ _UTM_LAT_MIN, _UTM_ZONE_MIN, \
60
60
  _UTM_ZONE_OFF_MAX, UtmUpsBase
61
61
 
62
62
  from math import asinh, atanh, atan2, cos, cosh, degrees, fabs, \
@@ -64,7 +64,7 @@ from math import asinh, atanh, atan2, cos, cosh, degrees, fabs, \
64
64
  # import operator as _operator # from .fmath
65
65
 
66
66
  __all__ = _ALL_LAZY.utm
67
- __version__ = '24.02.29'
67
+ __version__ = '24.05.21'
68
68
 
69
69
  _Bands = 'CDEFGHJKLMNPQRSTUVWXX' # UTM latitude bands C..X (no
70
70
  # I|O) 8° each, covering 80°S to 84°N and X repeated for 80-84°N
@@ -230,12 +230,13 @@ def _to4zBll(lat, lon, cmoff=True, strict=True, Error=RangeError):
230
230
  return Zone(z), (Band(B) if B else None), Lat(lat), Lon(lon)
231
231
 
232
232
 
233
- def _to7zBlldfn(latlon, lon, datum, falsed, name, zone, strict, Error, **cmoff):
233
+ def _to7zBlldfn(latlon, lon, datum, falsed, zone, strict, Error, **name_cmoff):
234
234
  '''(INTERNAL) Determine 7-tuple (zone, band, lat, lon, datum,
235
235
  falsed, name) for methods L{toEtm8} and L{toUtm8}.
236
236
  '''
237
- f = falsed and _xkwds_get(cmoff, cmoff=True) # DEPRECATED
238
- lat, lon, d, name = _to4lldn(latlon, lon, datum, name)
237
+ f, n = _xkwds_pop2(name_cmoff, cmoff=falsed) # DEPRECATED
238
+ n = _name__(**n) # _UnexpectedError
239
+ lat, lon, d, n = _to4lldn(latlon, lon, datum, n)
239
240
  z, B, lat, lon = _to4zBll(lat, lon, cmoff=f, strict=strict)
240
241
  if zone: # re-zone for ETM/UTM
241
242
  r, _, _ = _to3zBhp(zone, B)
@@ -245,7 +246,7 @@ def _to7zBlldfn(latlon, lon, datum, falsed, name, zone, strict, Error, **cmoff):
245
246
  if f: # re-offset from central meridian
246
247
  lon += _cmlon(z) - _cmlon(r)
247
248
  z = r
248
- return z, B, lat, lon, d, f, name
249
+ return z, B, lat, lon, d, f, n
249
250
 
250
251
 
251
252
  class Utm(UtmUpsBase):
@@ -260,7 +261,7 @@ class Utm(UtmUpsBase):
260
261
 
261
262
  def __init__(self, zone=31, hemisphere=_N_, easting=166022, # PYCHOK expected
262
263
  northing=0, band=NN, datum=_WGS84, falsed=True,
263
- gamma=None, scale=None, name=NN, **convergence):
264
+ gamma=None, scale=None, **name_convergence):
264
265
  '''New L{Utm} UTM coordinate.
265
266
 
266
267
  @kwarg zone: Longitudinal UTM zone (C{int}, 1..60) or zone with/-out
@@ -277,8 +278,8 @@ class Utm(UtmUpsBase):
277
278
  @kwarg gamma: Optional meridian convergence, bearing off grid North,
278
279
  clockwise from true North (C{degrees}) or C{None}.
279
280
  @kwarg scale: Optional grid scale factor (C{scalar}) or C{None}.
280
- @kwarg name: Optional name (C{str}).
281
- @kwarg convergence: DEPRECATED, use keyword argument C{B{gamma}=None}.
281
+ @kwarg name_convergence: Optional C{B{name}=NN} (C{str}) and DEPRECATED
282
+ C{B{convergence}=None}, instead use C{B{gamma}=None}.
282
283
 
283
284
  @raise TypeError: Invalid or near-spherical B{C{datum}}.
284
285
 
@@ -286,8 +287,11 @@ class Utm(UtmUpsBase):
286
287
  B{C{northing}}, B{C{band}}, B{C{convergence}} or
287
288
  B{C{scale}}.
288
289
  '''
289
- if name:
290
- self.name = name
290
+ c = name_convergence
291
+ if c:
292
+ n, c = _name2__(**c)
293
+ if n:
294
+ self.name = n
291
295
 
292
296
  self._zone, B, _ = _to3zBlat(zone, band)
293
297
 
@@ -309,7 +313,7 @@ class Utm(UtmUpsBase):
309
313
 
310
314
  self._hemisphere = h
311
315
  UtmUpsBase.__init__(self, e, n, band=B, datum=datum, falsed=falsed,
312
- gamma=gamma, scale=scale, **convergence)
316
+ gamma=gamma, scale=scale, **c)
313
317
 
314
318
  def __eq__(self, other):
315
319
  return isinstance(other, Utm) and other.zone == self.zone \
@@ -325,7 +329,7 @@ class Utm(UtmUpsBase):
325
329
  def __str__(self):
326
330
  return self.toStr()
327
331
 
328
- def _xcopy2(self, Xtm, name=NN):
332
+ def _xcopy2(self, Xtm, **name):
329
333
  '''(INTERNAL) Make copy as an B{C{Xtm}} instance.
330
334
 
331
335
  @arg Xtm: Class to return the copy (C{Xtm=Etm}, C{Xtm=Utm} or
@@ -333,7 +337,7 @@ class Utm(UtmUpsBase):
333
337
  '''
334
338
  return Xtm(self.zone, self.hemisphere, self.easting, self.northing,
335
339
  band=self.band, datum=self.datum, falsed=self.falsed,
336
- gamma=self.gamma, scale=self.scale, name=name or self.name)
340
+ gamma=self.gamma, scale=self.scale, name=self._name__(name))
337
341
 
338
342
  @property_doc_(''' the I{latitudinal} band.''')
339
343
  def band(self):
@@ -371,7 +375,7 @@ class Utm(UtmUpsBase):
371
375
  n = _FalseNorthing
372
376
  return EasNor2Tuple(e, n)
373
377
 
374
- def parse(self, strUTM, name=NN):
378
+ def parse(self, strUTM, **name):
375
379
  '''Parse a string to a similar L{Utm} instance.
376
380
 
377
381
  @arg strUTM: The UTM coordinate (C{str}),
@@ -386,7 +390,7 @@ class Utm(UtmUpsBase):
386
390
  @see: Functions L{pygeodesy.parseUPS5} and L{pygeodesy.parseUTMUPS5}.
387
391
  '''
388
392
  return parseUTM5(strUTM, datum=self.datum, Utm=self.classof,
389
- name=name or self.name)
393
+ name=self._name__(name))
390
394
 
391
395
  @deprecated_method
392
396
  def parseUTM(self, strUTM): # PYCHOK no cover
@@ -576,7 +580,7 @@ class Utm(UtmUpsBase):
576
580
  return self._zone
577
581
 
578
582
 
579
- def _parseUTM5(strUTM, datum, Xtm, falsed, Error=UTMError, name=NN): # imported by .etm
583
+ def _parseUTM5(strUTM, datum, Xtm, falsed, Error=UTMError, **name): # imported by .etm
580
584
  '''(INTERNAL) Parse a string representing a UTM coordinate,
581
585
  consisting of C{"zone[band] hemisphere easting northing"},
582
586
  see L{pygeodesy.parseETM5} and L{parseUTM5}.
@@ -585,16 +589,11 @@ def _parseUTM5(strUTM, datum, Xtm, falsed, Error=UTMError, name=NN): # imported
585
589
  if _UTM_ZONE_MIN > z or z > _UTM_ZONE_MAX or (B and B not in _Bands):
586
590
  raise Error(strUTM=strUTM, zone=z, band=B)
587
591
 
588
- if Xtm is None:
589
- r = UtmUps5Tuple(z, h, e, n, B, Error=Error, name=name)
590
- else:
591
- r = Xtm(z, h, e, n, band=B, datum=datum, falsed=falsed)
592
- if name:
593
- r = _xnamed(r, name, force=True)
594
- return r
592
+ return UtmUps5Tuple(z, h, e, n, B, Error=Error, **name) if Xtm is None else \
593
+ Xtm(z, h, e, n, band=B, datum=datum, falsed=falsed, **name)
595
594
 
596
595
 
597
- def parseUTM5(strUTM, datum=_WGS84, Utm=Utm, falsed=True, name=NN):
596
+ def parseUTM5(strUTM, datum=_WGS84, Utm=Utm, falsed=True, **name):
598
597
  '''Parse a string representing a UTM coordinate, consisting
599
598
  of C{"zone[band] hemisphere easting northing"}.
600
599
 
@@ -615,28 +614,29 @@ def parseUTM5(strUTM, datum=_WGS84, Utm=Utm, falsed=True, name=NN):
615
614
 
616
615
  @raise TypeError: Invalid B{C{datum}}.
617
616
  '''
618
- return _parseUTM5(strUTM, datum, Utm, falsed, name=name)
617
+ return _parseUTM5(strUTM, datum, Utm, falsed, **name)
619
618
 
620
619
 
621
620
  def toUtm8(latlon, lon=None, datum=None, Utm=Utm, falsed=True,
622
- name=NN, strict=True,
623
- zone=None, **cmoff):
621
+ strict=True, zone=None, **name_cmoff):
624
622
  '''Convert a lat-/longitude point to a UTM coordinate.
625
623
 
626
624
  @arg latlon: Latitude (C{degrees}) or an (ellipsoidal)
627
625
  geodetic C{LatLon} point.
628
- @kwarg lon: Optional longitude (C{degrees}) or C{None}.
626
+ @kwarg lon: Optional longitude (C{degrees}), required
627
+ if B{C{latlon}} is in C{degrees}.
629
628
  @kwarg datum: Optional datum for this UTM coordinate,
630
629
  overriding B{C{latlon}}'s datum (L{Datum},
631
630
  L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}).
632
631
  @kwarg Utm: Optional class to return the UTM coordinate
633
632
  (L{Utm}) or C{None}.
634
633
  @kwarg falsed: False both easting and northing (C{bool}).
635
- @kwarg name: Optional B{C{Utm}} name (C{str}).
636
634
  @kwarg strict: Restrict B{C{lat}} to UTM ranges (C{bool}).
637
635
  @kwarg zone: Optional UTM zone to enforce (C{int} or C{str}).
638
- @kwarg cmoff: DEPRECATED, use B{C{falsed}}. Offset longitude
639
- from the zone's central meridian (C{bool}).
636
+ @kwarg name_cmoff: Optional B{C{Utm}} C{B{name}=NN} (C{str})
637
+ and DEPRECATED C{B{cmoff}=True} to offset longitude
638
+ from the zone's central meridian (C{bool}), instead
639
+ use C{B{falsed}=True}.
640
640
 
641
641
  @return: The UTM coordinate (B{C{Utm}}) or if B{C{Utm}} is
642
642
  C{None} or not B{C{falsed}}, a L{UtmUps8Tuple}C{(zone,
@@ -651,17 +651,17 @@ def toUtm8(latlon, lon=None, datum=None, Utm=Utm, falsed=True,
651
651
 
652
652
  @raise UTMError: Invalid B{C{zone}}.
653
653
 
654
- @raise ValueError: If B{C{lon}} value is missing or if
655
- B{C{latlon}} is invalid.
654
+ @raise ValueError: If B{C{lon}} value is missing or B{C{latlon}}
655
+ is invalid.
656
656
 
657
657
  @note: Implements Karney’s method, using 8-th order Krüger series,
658
658
  giving results accurate to 5 nm (or better) for distances
659
659
  up to 3,900 Km from the central meridian.
660
660
  '''
661
- z, B, lat, lon, d, f, name = _to7zBlldfn(latlon, lon, datum,
662
- falsed, name, zone,
663
- strict, UTMError, **cmoff)
664
- d = _ellipsoidal_datum(d, name=name)
661
+ z, B, lat, lon, d, f, n = _to7zBlldfn(latlon, lon, datum,
662
+ falsed, zone, strict,
663
+ UTMError, **name_cmoff)
664
+ d = _ellipsoidal_datum(d, name=n)
665
665
  E = d.ellipsoid
666
666
 
667
667
  a, b = radians(lat), radians(lon)
@@ -681,8 +681,8 @@ def toUtm8(latlon, lon=None, datum=None, Utm=Utm, falsed=True,
681
681
  A0 = E.A * getattr(Utm, _under(_scale0_), _K0_UTM) # Utm is class or None
682
682
 
683
683
  K = _Kseries(E.AlphaKs, x, y) # Krüger series
684
- y = K.ys(y) * A0 # ξ
685
- x = K.xs(x) * A0 # η
684
+ y = K.ys(y) * A0 # ξ
685
+ x = K.xs(x) * A0 # η
686
686
 
687
687
  # convergence: Karney 2011 Eq 23, 24
688
688
  p_ = K.ps(1)
@@ -692,21 +692,21 @@ def toUtm8(latlon, lon=None, datum=None, Utm=Utm, falsed=True,
692
692
  k = E.e2s(sin(a)) * T12 / H * (A0 / E.a * hypot(p_, q_))
693
693
 
694
694
  return _toXtm8(Utm, z, lat, x, y,
695
- B, d, g, k, f, name, latlon, EPS)
695
+ B, d, g, k, f, n, latlon, EPS)
696
696
 
697
697
 
698
698
  def _toXtm8(Xtm, z, lat, x, y, B, d, g, k, f, # PYCHOK 13+ args
699
- name, latlon, eps, Error=UTMError):
699
+ n, latlon, eps, Error=UTMError):
700
700
  '''(INTERNAL) Helper for methods L{toEtm8} and L{toUtm8}.
701
701
  '''
702
702
  h = _hemi(lat)
703
703
  if f:
704
704
  x, y = _false2(x, y, h)
705
705
  if Xtm is None: # DEPRECATED
706
- r = UtmUps8Tuple(z, h, x, y, B, d, g, k, Error=Error, name=name)
706
+ r = UtmUps8Tuple(z, h, x, y, B, d, g, k, Error=Error, name=n)
707
707
  else:
708
- r = _xnamed(Xtm(z, h, x, y, band=B, datum=d, falsed=f,
709
- gamma=g, scale=k), name)
708
+ r = Xtm(z, h, x, y, band=B, datum=d, falsed=f,
709
+ gamma=g, scale=k, name=n)
710
710
  if isinstance(latlon, _LLEB) and d is latlon.datum: # see ups.toUtm8
711
711
  r._latlon5args(latlon, _toBand, f, eps) # XXX weakref(latlon)?
712
712
  latlon._gamma = g
@@ -716,7 +716,7 @@ def _toXtm8(Xtm, z, lat, x, y, B, d, g, k, f, # PYCHOK 13+ args
716
716
  return r
717
717
 
718
718
 
719
- def utmZoneBand5(lat, lon, cmoff=False, name=NN):
719
+ def utmZoneBand5(lat, lon, cmoff=False, **name):
720
720
  '''Return the UTM zone number, Band letter, hemisphere and
721
721
  (clipped) lat- and longitude for a given location.
722
722
 
@@ -738,7 +738,7 @@ def utmZoneBand5(lat, lon, cmoff=False, name=NN):
738
738
  '''
739
739
  lat, lon = parseDMS2(lat, lon)
740
740
  z, B, lat, lon = _to4zBll(lat, lon, cmoff=cmoff)
741
- return UtmUpsLatLon5Tuple(z, B, _hemi(lat), lat, lon, name=name)
741
+ return UtmUpsLatLon5Tuple(z, B, _hemi(lat), lat, lon, **name)
742
742
 
743
743
  # **) MIT License
744
744
  #