pygeodesy 24.5.8__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 (83) hide show
  1. {PyGeodesy-24.5.8.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 +16 -12
  4. pygeodesy/__main__.py +9 -10
  5. pygeodesy/albers.py +42 -42
  6. pygeodesy/auxilats/__init__.py +1 -1
  7. pygeodesy/auxilats/__main__.py +7 -10
  8. pygeodesy/auxilats/auxAngle.py +32 -31
  9. pygeodesy/auxilats/auxLat.py +81 -51
  10. pygeodesy/azimuthal.py +123 -124
  11. pygeodesy/basics.py +165 -176
  12. pygeodesy/booleans.py +14 -15
  13. pygeodesy/cartesianBase.py +25 -23
  14. pygeodesy/clipy.py +3 -3
  15. pygeodesy/constants.py +8 -6
  16. pygeodesy/css.py +50 -42
  17. pygeodesy/datums.py +50 -48
  18. pygeodesy/dms.py +6 -6
  19. pygeodesy/ecef.py +27 -27
  20. pygeodesy/elevations.py +2 -2
  21. pygeodesy/ellipsoidalBase.py +28 -27
  22. pygeodesy/ellipsoidalBaseDI.py +8 -7
  23. pygeodesy/ellipsoidalNvector.py +11 -12
  24. pygeodesy/ellipsoids.py +41 -35
  25. pygeodesy/elliptic.py +12 -10
  26. pygeodesy/epsg.py +4 -3
  27. pygeodesy/errors.py +35 -13
  28. pygeodesy/etm.py +62 -53
  29. pygeodesy/fmath.py +48 -41
  30. pygeodesy/formy.py +93 -65
  31. pygeodesy/frechet.py +117 -102
  32. pygeodesy/fstats.py +52 -46
  33. pygeodesy/fsums.py +169 -145
  34. pygeodesy/gars.py +10 -9
  35. pygeodesy/geodesicw.py +32 -30
  36. pygeodesy/geodesicx/__init__.py +1 -1
  37. pygeodesy/geodesicx/__main__.py +4 -4
  38. pygeodesy/geodesicx/gx.py +40 -32
  39. pygeodesy/geodesicx/gxarea.py +15 -12
  40. pygeodesy/geodesicx/gxbases.py +3 -4
  41. pygeodesy/geodesicx/gxline.py +6 -8
  42. pygeodesy/geodsolve.py +28 -26
  43. pygeodesy/geohash.py +47 -44
  44. pygeodesy/geoids.py +37 -35
  45. pygeodesy/hausdorff.py +112 -99
  46. pygeodesy/heights.py +136 -129
  47. pygeodesy/internals.py +576 -0
  48. pygeodesy/interns.py +6 -207
  49. pygeodesy/iters.py +22 -19
  50. pygeodesy/karney.py +18 -15
  51. pygeodesy/ktm.py +31 -24
  52. pygeodesy/latlonBase.py +12 -11
  53. pygeodesy/lazily.py +140 -218
  54. pygeodesy/lcc.py +24 -25
  55. pygeodesy/ltp.py +83 -71
  56. pygeodesy/ltpTuples.py +7 -5
  57. pygeodesy/mgrs.py +5 -4
  58. pygeodesy/named.py +136 -49
  59. pygeodesy/namedTuples.py +33 -25
  60. pygeodesy/nvectorBase.py +10 -9
  61. pygeodesy/osgr.py +14 -12
  62. pygeodesy/points.py +13 -13
  63. pygeodesy/props.py +7 -7
  64. pygeodesy/rhumb/__init__.py +1 -1
  65. pygeodesy/rhumb/bases.py +3 -2
  66. pygeodesy/rhumb/solve.py +2 -2
  67. pygeodesy/solveBase.py +8 -7
  68. pygeodesy/sphericalTrigonometry.py +5 -5
  69. pygeodesy/streprs.py +8 -7
  70. pygeodesy/trf.py +8 -8
  71. pygeodesy/triaxials.py +67 -63
  72. pygeodesy/units.py +48 -50
  73. pygeodesy/unitsBase.py +24 -11
  74. pygeodesy/ups.py +7 -6
  75. pygeodesy/utily.py +4 -4
  76. pygeodesy/utm.py +53 -52
  77. pygeodesy/utmupsBase.py +11 -8
  78. pygeodesy/vector2d.py +6 -7
  79. pygeodesy/vector3d.py +16 -17
  80. pygeodesy/vector3dBase.py +5 -5
  81. PyGeodesy-24.5.8.dist-info/RECORD +0 -115
  82. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
  83. {PyGeodesy-24.5.8.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/named.py CHANGED
@@ -14,25 +14,26 @@ standard Python C{namedtuple}s.
14
14
  '''
15
15
 
16
16
  from pygeodesy.basics import isclass, isidentifier, iskeyword, isstr, issubclassof, \
17
- itemsorted, len2, _sizeof, _xcopy, _xdup, _zip
17
+ itemsorted, len2, _xcopy, _xdup, _zip
18
18
  from pygeodesy.errors import _AssertionError, _AttributeError, _incompatible, \
19
19
  _IndexError, _IsnotError, _KeyError, LenError, \
20
20
  _NameError, _NotImplementedError, _TypeError, \
21
21
  _TypesError, UnitError, _ValueError, _xattr, _xkwds, \
22
- _xkwds_get, _xkwds_item2, _xkwds_pop2
22
+ _xkwds_item2, _xkwds_pop2
23
+ from pygeodesy.internals import _caller3, _dunder_nameof, _isPyPy, _sizeof, _under
23
24
  from pygeodesy.interns import MISSING, NN, _AT_, _COLON_, _COLONSPACE_, _COMMA_, \
24
- _COMMASPACE_, _doesn_t_exist_, _DOT_, _DUNDER_, _EQUAL_, \
25
- _exists_, _immutable_, _name_, _NL_, _NN_, _no_, _other_, \
26
- _s_, _SPACE_, _std_, _UNDER_, _valid_, _vs_, \
27
- _dunder_nameof, _isPyPy, _under
28
- from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _caller3, _getenv
25
+ _COMMASPACE_, _doesn_t_exist_, _DOT_, _DUNDER_, \
26
+ _dunder_name_, _EQUAL_, _exists_, _immutable_, _name_, \
27
+ _NL_, _NN_, _no_, _other_, _s_, _SPACE_, _std_, \
28
+ _UNDER_, _valid_, _vs_
29
+ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
29
30
  from pygeodesy.props import _allPropertiesOf_n, deprecated_method, _hasProperty, \
30
31
  _update_all, property_doc_, Property_RO, property_RO, \
31
32
  _update_attrs
32
33
  from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
33
34
 
34
35
  __all__ = _ALL_LAZY.named
35
- __version__ = '24.05.04'
36
+ __version__ = '24.05.21'
36
37
 
37
38
  _COMMANL_ = _COMMA_ + _NL_
38
39
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
@@ -44,32 +45,37 @@ _name = _under(_name_)
44
45
  _Names_ = '_Names_'
45
46
  _registered_ = 'registered' # PYCHOK used!
46
47
  _std_NotImplemented = _getenv('PYGEODESY_NOTIMPLEMENTED', NN).lower() == _std_
48
+ _such_ = 'such'
47
49
  _Units_ = '_Units_'
48
50
  _UP = 2
49
51
 
50
52
 
51
- def _xjoined_(prefix, name, enquote=True):
52
- '''(INTERNAL) Join C{pref} and non-empty C{name}.
53
+ def _xjoined_(prefix, name=NN, enquote=True, **name__of_name):
54
+ '''(INTERNAL) Join C{prefix} and non-empty C{name}.
53
55
  '''
56
+ if name__of_name:
57
+ name = _name__(name, **name__of_name)
54
58
  if name and prefix:
55
59
  if enquote:
56
60
  name = repr(name)
57
- n = _SPACE_(prefix, name)
61
+ t = _SPACE_(prefix, name)
58
62
  else:
59
- n = prefix or name
60
- return n
63
+ t = prefix or name
64
+ return t
61
65
 
62
66
 
63
- def _xnamed(inst, name, force=False):
67
+ def _xnamed(inst, name=NN, force=False, **name__of_name):
64
68
  '''(INTERNAL) Set the instance' C{.name = B{name}}.
65
69
 
66
70
  @arg inst: The instance (C{_Named}).
67
- @arg name: The name (C{str}).
68
- @kwarg force: Force name change (C{bool}).
71
+ @kwarg name: The name (C{str}).
72
+ @kwarg force: If C{True}, force rename (C{bool}).
69
73
 
70
- @return: The B{C{inst}}, named if B{C{force}}d or
71
- not named before.
74
+ @return: The B{C{inst}}, renamed if B{C{force}}d
75
+ or if not named before.
72
76
  '''
77
+ if name__of_name:
78
+ name = _name__(name, **name__of_name)
73
79
  if name and isinstance(inst, _Named):
74
80
  if not inst.name:
75
81
  inst.name = name
@@ -84,7 +90,7 @@ def _xother3(inst, other, name=_other_, up=1, **name_other):
84
90
  if name_other: # and other is None
85
91
  name, other = _xkwds_item2(name_other)
86
92
  elif other and len(other) == 1:
87
- other = other[0]
93
+ name, other = _name__(name), other[0]
88
94
  else:
89
95
  raise _AssertionError(name, other, txt=classname(inst, prefixed=True))
90
96
  return other, name, up
@@ -164,6 +170,7 @@ class ADict(dict):
164
170
  C{floats} formatted by function L{pygeodesy.fstr}.
165
171
  '''
166
172
  n = _xattr(self, name=NN) or self.__class__.__name__
173
+ print(1, n)
167
174
  return Fmt.PAREN(n, self._toT(_EQUAL_, **prec_fmt))
168
175
 
169
176
  def toStr(self, **prec_fmt):
@@ -258,18 +265,18 @@ class _Named(object):
258
265
  '''
259
266
  return _xnamed(self.__class__(*args, **kwds), self.name)
260
267
 
261
- def copy(self, deep=False, name=NN):
268
+ def copy(self, deep=False, **name):
262
269
  '''Make a shallow or deep copy of this instance.
263
270
 
264
271
  @kwarg deep: If C{True} make a deep, otherwise
265
272
  a shallow copy (C{bool}).
266
- @kwarg name: Optional, non-empty name (C{str}).
273
+ @kwarg name: Optional, non-empty C{B{name}=NN} (C{str}).
267
274
 
268
275
  @return: The copy (C{This class}).
269
276
  '''
270
277
  c = _xcopy(self, deep=deep)
271
278
  if name:
272
- c.rename(name)
279
+ _ = c.rename(name)
273
280
  return c
274
281
 
275
282
  def _DOT_(self, *names):
@@ -281,7 +288,8 @@ class _Named(object):
281
288
  '''Duplicate this instance, replacing some attributes.
282
289
 
283
290
  @kwarg deep: If C{True} duplicate deep, otherwise shallow.
284
- @kwarg items: Attributes to be changed (C{any}).
291
+ @kwarg items: Attributes to be changed (C{any}), including
292
+ optional C{B{name}} (C{str}).
285
293
 
286
294
  @return: The duplicate (C{This class}).
287
295
 
@@ -291,7 +299,7 @@ class _Named(object):
291
299
  m, items = _xkwds_pop2(items, name=n)
292
300
  d = _xdup(self, deep=deep, **items)
293
301
  if m != n:
294
- d.rename(m)
302
+ d.rename(m) # zap _Named_Property_ROs
295
303
  # if items:
296
304
  # _update_all(d)
297
305
  return d
@@ -340,11 +348,11 @@ class _Named(object):
340
348
 
341
349
  @name.setter # PYCHOK setter!
342
350
  def name(self, name):
343
- '''Set the name (C{str}).
351
+ '''Set the C{B{name}=NN} (C{str}).
344
352
 
345
353
  @raise NameError: Can't rename, use method L{rename}.
346
354
  '''
347
- m, n = self._name, str(name)
355
+ m, n = self._name, _name__(name)
348
356
  if not m:
349
357
  self._name = n
350
358
  elif n != m:
@@ -360,6 +368,11 @@ class _Named(object):
360
368
  # _Named.name.fset(self, name), but NOT
361
369
  # _Named(self).name = name
362
370
 
371
+ def _name__(self, name): # usually **name
372
+ '''(INTERNAL) Get the C{name} or this C{name}.
373
+ '''
374
+ return _name__(name, _or_nameof=self) # nameof(self)
375
+
363
376
  @Property_RO
364
377
  def named(self):
365
378
  '''Get the name I{or} class name or C{""} (C{str}).
@@ -407,12 +420,22 @@ class _Named(object):
407
420
 
408
421
  @return: The previous name (C{str}).
409
422
  '''
410
- m, n = self._name, str(name)
423
+ m, n = self._name, _name__(name)
411
424
  if n != m:
412
425
  self._name = n
413
426
  _update_attrs(self, *_Named_Property_ROs)
414
427
  return m
415
428
 
429
+ def renamed(self, name):
430
+ '''Change the name.
431
+
432
+ @arg name: The new name (C{str}).
433
+
434
+ @return: This instance (C{str}).
435
+ '''
436
+ _ = self.rename(name)
437
+ return self
438
+
416
439
  @property_RO
417
440
  def sizeof(self):
418
441
  '''Get the current size in C{bytes} of this instance (C{int}).
@@ -442,16 +465,17 @@ class _Named(object):
442
465
  # '''
443
466
  # return _DOT_(self, unstr(which, *args, **kwds))
444
467
 
445
- def _xnamed(self, inst, name=NN, force=False):
468
+ def _xnamed(self, inst, name=NN, **force):
446
469
  '''(INTERNAL) Set the instance' C{.name = self.name}.
447
470
 
448
471
  @arg inst: The instance (C{_Named}).
449
- @kwarg name: Optional name, overriding C{self.name} (C{str}).
450
- @kwarg force: Force name change (C{bool}).
472
+ @kwarg name: The name (C{str}).
473
+ @kwarg force: If C{True}, force rename (C{bool}).
451
474
 
452
- @return: The B{C{inst}}, named if not named before.
475
+ @return: The B{C{inst}}, renamed if B{C{force}}d
476
+ or if not named before.
453
477
  '''
454
- return _xnamed(inst, name or self.name, force=force)
478
+ return _xnamed(inst, name, **force)
455
479
 
456
480
  def _xrenamed(self, inst):
457
481
  '''(INTERNAL) Rename the instance' C{.name = self.name}.
@@ -465,7 +489,7 @@ class _Named(object):
465
489
  if not isinstance(inst, _Named):
466
490
  raise _IsnotError(_valid_, inst=inst)
467
491
 
468
- inst.rename(self.name)
492
+ _ = inst.rename(self.name)
469
493
  return inst
470
494
 
471
495
  _Named_Property_ROs = _allPropertiesOf_n(5, _Named, Property_RO) # PYCHOK once
@@ -558,16 +582,17 @@ class _NamedBase(_Named):
558
582
 
559
583
 
560
584
  class _NamedDict(ADict, _Named):
561
- '''(INTERNAL) Named C{dict} with key I{and} attribute
562
- access to the items.
585
+ '''(INTERNAL) Named C{dict} with key I{and} attribute access
586
+ to the items.
563
587
  '''
564
588
  def __init__(self, *args, **kwds):
565
- if args: # args override kwds
589
+ if args: # is args[0] a dict?
566
590
  if len(args) != 1: # or not isinstance(args[0], dict)
591
+ kwds = _name1__(kwds)
567
592
  t = unstr(self.classname, *args, **kwds) # PYCHOK no cover
568
593
  raise _ValueError(args=len(args), txt=t)
569
- kwds = _xkwds(dict(args[0]), **kwds)
570
- n, kwds = _xkwds_pop2(kwds, name=NN)
594
+ kwds = _xkwds(dict(args[0]), **kwds) # args[0] overrides kwds
595
+ n, kwds = _name2__(**kwds)
571
596
  if n:
572
597
  _Named.name.fset(self, n) # see _Named.name
573
598
  ADict.__init__(self, kwds)
@@ -639,7 +664,7 @@ class _NamedEnum(_NamedDict):
639
664
  @arg Classes: Additional, acceptable classes or C{type}s.
640
665
  '''
641
666
  self._item_Classes = (Class,) + Classes
642
- n = _xkwds_get(name, name=NN) or NN(Class.__name__, _s_)
667
+ n = _name__(**name) or NN(Class.__name__, _s_) # _dunder_nameof
643
668
  if n and _xvalid(n, underOK=True):
644
669
  _Named.name.fset(self, n) # see _Named.name
645
670
 
@@ -662,12 +687,13 @@ class _NamedEnum(_NamedDict):
662
687
  '''(INTERNAL) Check attribute name against given, registered name.
663
688
  '''
664
689
  pypy = _isPyPy()
690
+ _isa = isinstance
665
691
  for n, v in kwds.items():
666
- if isinstance(v, _LazyNamedEnumItem): # property
692
+ if _isa(v, _LazyNamedEnumItem): # property
667
693
  assert (n == v.name) if pypy else (n is v.name)
668
694
  # assert not hasattr(self.__class__, n)
669
695
  setattr(self.__class__, n, v)
670
- elif isinstance(v, self._item_Classes): # PYCHOK no cover
696
+ elif _isa(v, self._item_Classes): # PYCHOK no cover
671
697
  assert self[n] is v and getattr(self, n) \
672
698
  and self.find(v) == n
673
699
  else:
@@ -710,8 +736,9 @@ class _NamedEnum(_NamedDict):
710
736
  case-insensitive} order (C{bool}).
711
737
  '''
712
738
  if all: # instantiate any remaining L{_LazyNamedEnumItem}
739
+ _isa = isinstance
713
740
  for n, p in tuple(self.__class__.__dict__.items()):
714
- if isinstance(p, _LazyNamedEnumItem):
741
+ if _isa(p, _LazyNamedEnumItem):
715
742
  _ = getattr(self, n)
716
743
  return itemsorted(self) if asorted else ADict.items(self)
717
744
 
@@ -778,7 +805,7 @@ class _NamedEnum(_NamedDict):
778
805
  else:
779
806
  name = self.find(name_or_item, dflt=MISSING) # all=True?
780
807
  if name is MISSING:
781
- t = _SPACE_(_no_, 'such', self.classname, _item_)
808
+ t = _SPACE_(_no_, _such_, self.classname, _item_)
782
809
  raise _AttributeError(t, txt=repr(name_or_item))
783
810
  try:
784
811
  item = ADict.pop(self, name)
@@ -878,9 +905,11 @@ class _NamedEnumItem(_NamedBase):
878
905
  def name(self, name):
879
906
  '''Set the name, unless already registered (C{str}).
880
907
  '''
908
+ name = _name__(name) or _NN_
881
909
  if self._enum:
882
- raise _NameError(str(name), self, txt=_registered_) # XXX _TypeError
883
- self._name = str(name)
910
+ raise _NameError(name, self, txt=_registered_) # XXX _TypeError
911
+ if name:
912
+ self._name = name
884
913
 
885
914
  def _register(self, enum, name):
886
915
  '''(INTERNAL) Add this item as B{C{enum.name}}.
@@ -888,6 +917,7 @@ class _NamedEnumItem(_NamedBase):
888
917
  @note: Don't register if name is empty or doesn't
889
918
  start with a letter.
890
919
  '''
920
+ name = _name__(name)
891
921
  if name and _xvalid(name, underOK=True):
892
922
  self.name = name
893
923
  if name[:1].isalpha(): # '_...' not registered
@@ -1040,7 +1070,7 @@ class _NamedTuple(tuple, _Named):
1040
1070
 
1041
1071
  iteritems = items
1042
1072
 
1043
- def _kwdself(self, iteration=None, name=NN, **unused):
1073
+ def _kwdself(self, iteration=None, **name):
1044
1074
  '''(INTERNAL) Set C{__new__} keyword arguments.
1045
1075
  '''
1046
1076
  if iteration is not None:
@@ -1141,7 +1171,8 @@ class _NamedTuple(tuple, _Named):
1141
1171
  if (issubclassof(xTuple, _NamedTuple) and
1142
1172
  (len(self._Names_) + len(items)) == len(xTuple._Names_) and
1143
1173
  self._Names_ == xTuple._Names_[:len(self)]):
1144
- return xTuple(self + items, **_xkwds(name, name=self.name)) # *(self + items)
1174
+ n = _name__(**name) or self.name
1175
+ return xTuple(self + items, name=n) # *(self + items)
1145
1176
  c = NN(self.classname, repr(self._Names_)) # PYCHOK no cover
1146
1177
  x = NN(xTuple.__name__, repr(xTuple._Names_)) # PYCHOK no cover
1147
1178
  raise TypeError(_SPACE_(c, _vs_, x))
@@ -1229,9 +1260,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1229
1260
  @return: The B{C{class}}'s C{[module.]class} name (C{str}).
1230
1261
  '''
1231
1262
  try:
1232
- n = clas.__name__
1263
+ n = clas.__name__
1233
1264
  except AttributeError:
1234
- n = '__name__' # _DUNDER_(NN, _name_, NN)
1265
+ n = _dunder_name_
1235
1266
  if prefixed or (classnaming() if prefixed is None else False):
1236
1267
  try:
1237
1268
  m = clas.__module__.rsplit(_DOT_, 1)
@@ -1241,6 +1272,62 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1241
1272
  return n
1242
1273
 
1243
1274
 
1275
+ # def _name__(name=NN, name__=None, _or_nameof=None, **kwds):
1276
+ # '''(INTERNAL) Get single keyword argument C{B{name}=NN|None}.
1277
+ # '''
1278
+ # if kwds: # "unexpected keyword arguments ..."
1279
+ # m = _MODS.errors
1280
+ # raise m._UnexpectedError(**kwds)
1281
+ # if name: # is given
1282
+ # n = _name__(**name) if isinstance(name, dict) else str(name)
1283
+ # elif name__ is not None:
1284
+ # n = getattr(name__, _dunder_name_, NN) # _xattr(name__, __name__=NN)
1285
+ # else:
1286
+ # n = name # NN or None or {} or any False type
1287
+ # if _or_nameof is not None and not n:
1288
+ # n = getattr(_or_nameof, _name_, NN) # _xattr(_or_nameof, name=NN)
1289
+ # return n # str or None or {}
1290
+
1291
+
1292
+ def _name__(name=NN, **kwds):
1293
+ '''(INTERNAL) Get single keyword argument C{B{name}=NN|None}.
1294
+ '''
1295
+ if name or kwds:
1296
+ name, kwds = _name2__(name, **kwds)
1297
+ if kwds: # "unexpected keyword arguments ..."
1298
+ m = _MODS.errors
1299
+ raise m._UnexpectedError(**kwds)
1300
+ return name if name or name is None else NN
1301
+
1302
+
1303
+ def _name1__(kwds_name, _or_nameof=None):
1304
+ '''(INTERNAL) Resolve and set the C{B{name}=NN}.
1305
+ '''
1306
+ if kwds_name:
1307
+ n, kwds_name = _name2__(kwds_name, _or_nameof=_or_nameof)
1308
+ if n:
1309
+ kwds_name.update(name=n)
1310
+ return kwds_name
1311
+
1312
+
1313
+ def _name2__(name=NN, name__=None, _or_nameof=None, **kwds):
1314
+ '''(INTERNAL) Get the C{B{name}=NN|None} and other C{kwds}.
1315
+ '''
1316
+ if name: # is given
1317
+ if isinstance(name, dict):
1318
+ kwds.update(name) # kwds = _xkwds(kwds, **name)?
1319
+ n, kwds = _name2__(**kwds)
1320
+ else:
1321
+ n = str(name)
1322
+ elif name__ is not None:
1323
+ n = getattr(name__, _dunder_name_, NN) # _xattr(name__, __name__=NN)
1324
+ else:
1325
+ n = name if name is None else NN
1326
+ if _or_nameof is not None and not n:
1327
+ n = getattr(_or_nameof, _name_, NN) # _xattr(_or_nameof, name=NN)
1328
+ return n, kwds # (str or None or {}), dict
1329
+
1330
+
1244
1331
  def nameof(inst):
1245
1332
  '''Get the name of an instance.
1246
1333
 
pygeodesy/namedTuples.py CHANGED
@@ -11,13 +11,13 @@ of C{_NamedTuple} defined in C{pygeodesy.named}.
11
11
  from pygeodesy.basics import map1, _xinstanceof
12
12
  # from pygeodesy.constants import INT0 # from .units
13
13
  from pygeodesy.errors import _ALL_LAZY, _MODS, _xattr, _xkwds_not # _xkwds
14
- from pygeodesy.interns import NN, _1_, _2_, _a_, _A_, _area_, _angle_, _b_, \
15
- _B_, _band_, _c_, _C_, _datum_, _D_, _distance_, \
16
- _E_, _easting_, _end_, _fi_, _gamma_, _height_, \
17
- _h_, _j_, _hemipole_, _initial_, _lam_, _lat_, \
18
- _lon_, _n_, _northing_, _number_, _outside_, \
19
- _phi_, _point_, _precision_, _points_, _radius_, \
20
- _scale_, _start_, _x_, _y_, _z_, _zone_
14
+ from pygeodesy.interns import _1_, _2_, _a_, _A_, _area_, _angle_, _b_, _B_, \
15
+ _band_, _c_, _C_, _datum_, _D_, _distance_, \
16
+ _E_, _easting_, _end_, _fi_, _gamma_, _height_, \
17
+ _h_, _j_, _hemipole_, _initial_, _lam_, _lat_, \
18
+ _lon_, _n_, _northing_, _number_, _outside_, \
19
+ _phi_, _point_, _precision_, _points_, _radius_, \
20
+ _scale_, _start_, _x_, _y_, _z_, _zone_
21
21
  # from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .errors
22
22
  from pygeodesy.named import _NamedTuple, _Pass
23
23
  from pygeodesy.props import deprecated_property_RO, property_RO
@@ -27,7 +27,7 @@ from pygeodesy.units import Band, Bearing, Degrees, Degrees2, Easting, \
27
27
  Radians, Radius, Scalar, Str
28
28
 
29
29
  __all__ = _ALL_LAZY.namedTuples
30
- __version__ = '23.12.07'
30
+ __version__ = '24.05.18'
31
31
 
32
32
  # __DUNDER gets mangled in class
33
33
  _closest_ = 'closest'
@@ -202,7 +202,8 @@ class LatLon2Tuple(_NamedTuple):
202
202
  '''Extend this L{LatLon2Tuple} to a L{LatLon3Tuple}.
203
203
 
204
204
  @arg height: The height to add (C{scalar}).
205
- @kwarg name: Optional name (C{str}), overriding this name.
205
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding
206
+ this name.
206
207
 
207
208
  @return: A L{LatLon3Tuple}C{(lat, lon, height)}.
208
209
 
@@ -215,7 +216,8 @@ class LatLon2Tuple(_NamedTuple):
215
216
 
216
217
  @arg height: The height to add (C{scalar}).
217
218
  @arg datum: The datum to add (C{Datum}).
218
- @kwarg name: Optional name (C{str}), overriding this name.
219
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding
220
+ this name.
219
221
 
220
222
  @return: A L{LatLon4Tuple}C{(lat, lon, height, datum)}.
221
223
 
@@ -237,7 +239,8 @@ class LatLon3Tuple(_NamedTuple):
237
239
  '''Extend this L{LatLon3Tuple} to a L{LatLon4Tuple}.
238
240
 
239
241
  @arg datum: The datum to add (C{Datum}).
240
- @kwarg name: Optional name (C{str}), overriding this name.
242
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding
243
+ this name.
241
244
 
242
245
  @return: A L{LatLon4Tuple}C{(lat, lon, height, datum)}.
243
246
 
@@ -256,17 +259,17 @@ class LatLon4Tuple(LatLon3Tuple): # .cartesianBase, .css, .ecef, .lcc
256
259
 
257
260
 
258
261
  def _LL4Tuple(lat, lon, height, datum, LatLon, LatLon_kwds, inst=None,
259
- iteration=None, name=NN):
262
+ iteration=None, **name):
260
263
  '''(INTERNAL) Return a L{LatLon4Tuple} or a B{C{LatLon}} instance.
261
264
  '''
262
265
  if LatLon is None: # ignore LatLon_kwds
263
- r = LatLon4Tuple(lat, lon, height, datum, name=name)
266
+ r = LatLon4Tuple(lat, lon, height, datum, **name)
264
267
  else:
265
268
  kwds = {} if inst is None else _xkwds_not(None,
266
269
  # datum=_xattr(inst, datum=None),
267
270
  epoch=_xattr(inst, epoch=None),
268
271
  reframe=_xattr(inst, reframe=None)) # PYCHOK indent
269
- kwds.update(datum=datum, height=height, name=name)
272
+ kwds.update(datum=datum, height=height, **name)
270
273
  if LatLon_kwds:
271
274
  kwds.update(LatLon_kwds)
272
275
  r = LatLon(lat, lon, **kwds)
@@ -303,7 +306,8 @@ class LatLonPrec3Tuple(_NamedTuple): # .gars.py, .wgrs.py
303
306
 
304
307
  @arg height: The height to add (C{float} or C{None}).
305
308
  @arg radius: The radius to add (C{float} or C{None}).
306
- @kwarg name: Optional name (C{str}), overriding this name.
309
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding
310
+ this name.
307
311
 
308
312
  @return: A L{LatLonPrec5Tuple}C{(lat, lon, precision,
309
313
  height, radius)}.
@@ -401,7 +405,8 @@ class PhiLam2Tuple(_NamedTuple): # .frechet, .hausdorff, .latlonBase, .points,
401
405
  '''Extend this L{PhiLam2Tuple} to a L{PhiLam3Tuple}.
402
406
 
403
407
  @arg height: The height to add (C{scalar}).
404
- @kwarg name: Optional name (C{str}), overriding this name.
408
+ @kwarg name: Optional C{B{name}=NN} (C{str}),
409
+ overriding this name.
405
410
 
406
411
  @return: A L{PhiLam3Tuple}C{(phi, lam, height)}.
407
412
 
@@ -440,7 +445,8 @@ class PhiLam3Tuple(_NamedTuple): # .nvector.py, extends -2Tuple
440
445
  '''Extend this L{PhiLam3Tuple} to a L{PhiLam4Tuple}.
441
446
 
442
447
  @arg datum: The datum to add (C{Datum}).
443
- @kwarg name: Optional name (C{str}), overriding this name.
448
+ @kwarg name: Optional C{B{name}=NN} (C{str}),
449
+ overriding this name.
444
450
 
445
451
  @return: A L{PhiLam4Tuple}C{(phi, lam, height, datum)}.
446
452
 
@@ -546,11 +552,11 @@ class UtmUps5Tuple(_NamedTuple): # .mgrs.py, .ups.py, .utm.py, .utmups.py
546
552
  _Names_ = (_zone_, _hemipole_, _easting_, _northing_, _band_)
547
553
  _Units_ = ( Number_, Str, Easting, Northing, Band)
548
554
 
549
- def __new__(cls, z, h, e, n, B, Error=None, name=NN):
555
+ def __new__(cls, z, h, e, n, B, Error=None, **name):
550
556
  if Error is not None:
551
557
  e = Easting( e, Error=Error)
552
558
  n = Northing(n, Error=Error)
553
- return _NamedTuple.__new__(cls, z, h, e, n, B, name=name)
559
+ return _NamedTuple.__new__(cls, z, h, e, n, B, **name)
554
560
 
555
561
 
556
562
  class UtmUps8Tuple(_NamedTuple, _Convergence): # .ups, .utm, .utmups
@@ -567,13 +573,13 @@ class UtmUps8Tuple(_NamedTuple, _Convergence): # .ups, .utm, .utmups
567
573
  _Units_ = ( Number_, Str, Easting, Northing,
568
574
  Band, _Pass, Degrees, Scalar)
569
575
 
570
- def __new__(cls, z, h, e, n, B, d, g, s, Error=None, name=NN): # PYCHOK 11 args
576
+ def __new__(cls, z, h, e, n, B, d, g, s, Error=None, **name): # PYCHOK 11 args
571
577
  if Error is not None:
572
578
  e = Easting( e, Error=Error)
573
579
  n = Northing(n, Error=Error)
574
580
  g = Degrees(gamma=g, Error=Error)
575
581
  s = Scalar(scale=s, Error=Error)
576
- return _NamedTuple.__new__(cls, z, h, e, n, B, d, g, s, name=name)
582
+ return _NamedTuple.__new__(cls, z, h, e, n, B, d, g, s, **name)
577
583
 
578
584
 
579
585
  class UtmUpsLatLon5Tuple(_NamedTuple): # .ups.py, .utm.py, .utmups.py
@@ -587,11 +593,11 @@ class UtmUpsLatLon5Tuple(_NamedTuple): # .ups.py, .utm.py, .utmups.py
587
593
  _Names_ = (_zone_, _band_, _hemipole_, _lat_, _lon_)
588
594
  _Units_ = ( Number_, Band, Str, Lat, Lon)
589
595
 
590
- def __new__(cls, z, B, h, lat, lon, Error=None, name=NN):
596
+ def __new__(cls, z, B, h, lat, lon, Error=None, **name):
591
597
  if Error is not None:
592
598
  lat = Lat(lat, Error=Error)
593
599
  lon = Lon(lon, Error=Error)
594
- return _NamedTuple.__new__(cls, z, B, h, lat, lon, name=name)
600
+ return _NamedTuple.__new__(cls, z, B, h, lat, lon, **name)
595
601
 
596
602
 
597
603
  class Vector2Tuple(_NamedTuple):
@@ -605,7 +611,8 @@ class Vector2Tuple(_NamedTuple):
605
611
  '''Extend this L{Vector2Tuple} to a L{Vector3Tuple}.
606
612
 
607
613
  @kwarg z: The Z component add (C{scalar}).
608
- @kwarg name: Optional name (C{str}), overriding this name.
614
+ @kwarg name: Optional C{B{name}=NN} (C{str}),
615
+ overriding this name.
609
616
 
610
617
  @return: A L{Vector3Tuple}C{(x, y, z)}.
611
618
 
@@ -625,7 +632,8 @@ class Vector3Tuple(_NamedTuple):
625
632
  '''Extend this L{Vector3Tuple} to a L{Vector4Tuple}.
626
633
 
627
634
  @arg h: The height to add (C{scalar}).
628
- @kwarg name: Optional name (C{str}), overriding this name.
635
+ @kwarg name: Optional C{B{name}=NN} (C{str}),
636
+ overriding this name.
629
637
 
630
638
  @return: A L{Vector4Tuple}C{(x, y, z, h)}.
631
639
 
pygeodesy/nvectorBase.py CHANGED
@@ -19,13 +19,14 @@ from pygeodesy.fmath import fdot, fidw, hypot_ # PYCHOK fdot shared
19
19
  from pygeodesy.fsums import Fsum, fsumf_
20
20
  from pygeodesy.formy import _isequalTo, n_xyz2latlon, n_xyz2philam, \
21
21
  _spherical_datum
22
+ # from pygeodesy.internals import _under # from .named
22
23
  from pygeodesy.interns import NN, _1_, _2_, _3_, _bearing_, _coincident_, \
23
24
  _COMMASPACE_, _distance_, _h_, _insufficient_, \
24
25
  _intersection_, _no_, _NorthPole_, _point_, \
25
- _pole_, _SPACE_, _SouthPole_, _under
26
+ _pole_, _SPACE_, _SouthPole_
26
27
  from pygeodesy.latlonBase import LatLonBase, _ALL_DOCS, _ALL_LAZY, _MODS
27
28
  # from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS # from .latlonBase
28
- from pygeodesy.named import _xother3
29
+ from pygeodesy.named import _xother3, _under
29
30
  from pygeodesy.namedTuples import Trilaterate5Tuple, Vector3Tuple, \
30
31
  Vector4Tuple, map1
31
32
  from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
@@ -38,7 +39,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdn3
38
39
  from math import fabs, sqrt
39
40
 
40
41
  __all__ = _ALL_LAZY.nvectorBase
41
- __version__ = '24.04.07'
42
+ __version__ = '24.05.18'
42
43
 
43
44
 
44
45
  class NvectorBase(Vector3d): # XXX kept private
@@ -48,7 +49,7 @@ class NvectorBase(Vector3d): # XXX kept private
48
49
  _h = Height(h=0) # height (C{meter})
49
50
  _H = NN # height prefix (C{str}), '↑' in JS version
50
51
 
51
- def __init__(self, x_xyz, y=None, z=None, h=0, ll=None, datum=None, name=NN):
52
+ def __init__(self, x_xyz, y=None, z=None, h=0, ll=None, datum=None, **name):
52
53
  '''New n-vector normal to the earth's surface.
53
54
 
54
55
  @arg x_xyz: X component of vector (C{scalar}) or (3-D) vector
@@ -61,15 +62,15 @@ class NvectorBase(Vector3d): # XXX kept private
61
62
  @kwarg h: Optional height above surface (C{meter}).
62
63
  @kwarg ll: Optional, original latlon (C{LatLon}).
63
64
  @kwarg datum: Optional, I{pass-thru} datum (L{Datum}).
64
- @kwarg name: Optional name (C{str}).
65
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
65
66
 
66
67
  @raise TypeError: Non-scalar B{C{x}}, B{C{y}} or B{C{z}}
67
68
  coordinate or B{C{x}} not an C{Nvector},
68
69
  L{Vector3Tuple} or L{Vector4Tuple} or
69
70
  invalid B{C{datum}}.
70
71
  '''
71
- h, d, n = _xyzhdn3(x_xyz, h, datum, ll)
72
- Vector3d.__init__(self, x_xyz, y=y, z=z, ll=ll, name=name or n)
72
+ h, d, n = _xyzhdn3(x_xyz, h, datum, ll, **name)
73
+ Vector3d.__init__(self, x_xyz, y=y, z=z, ll=ll, name=n)
73
74
  if h:
74
75
  self.h = h
75
76
  if d is not None:
@@ -460,8 +461,8 @@ class LatLonNvectorBase(LatLonBase):
460
461
  @arg bearing1: Bearing at this point (compass C{degrees360}).
461
462
  @arg other: The other point (C{LatLon}).
462
463
  @arg bearing2: Bearing at the other point (compass C{degrees360}).
463
- @kwarg height: Optional height at the triangulated point,
464
- overriding the mean height (C{meter}).
464
+ @kwarg height: Optional height at the triangulated point, overriding
465
+ the mean height (C{meter}).
465
466
  @kwarg wrap: If C{True}, use this and the B{C{other}} point
466
467
  I{normalized} (C{bool}).
467
468