pygeodesy 25.4.8__py2.py3-none-any.whl → 25.5.5__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 (97) hide show
  1. pygeodesy/__init__.py +36 -31
  2. pygeodesy/__main__.py +3 -3
  3. pygeodesy/albers.py +29 -36
  4. pygeodesy/auxilats/_CX_4.py +2 -2
  5. pygeodesy/auxilats/_CX_6.py +2 -2
  6. pygeodesy/auxilats/_CX_8.py +2 -2
  7. pygeodesy/auxilats/_CX_Rs.py +9 -9
  8. pygeodesy/auxilats/__init__.py +3 -3
  9. pygeodesy/auxilats/__main__.py +8 -6
  10. pygeodesy/auxilats/auxAngle.py +2 -2
  11. pygeodesy/auxilats/auxLat.py +5 -5
  12. pygeodesy/auxilats/auxily.py +5 -3
  13. pygeodesy/azimuthal.py +7 -6
  14. pygeodesy/basics.py +32 -18
  15. pygeodesy/booleans.py +18 -16
  16. pygeodesy/cartesianBase.py +26 -24
  17. pygeodesy/clipy.py +11 -10
  18. pygeodesy/constants.py +11 -10
  19. pygeodesy/css.py +14 -11
  20. pygeodesy/datums.py +8 -8
  21. pygeodesy/deprecated/bases.py +2 -2
  22. pygeodesy/deprecated/classes.py +2 -2
  23. pygeodesy/deprecated/consterns.py +4 -4
  24. pygeodesy/dms.py +8 -8
  25. pygeodesy/ecef.py +22 -29
  26. pygeodesy/ecefLocals.py +186 -0
  27. pygeodesy/elevations.py +9 -8
  28. pygeodesy/ellipsoidalBase.py +19 -8
  29. pygeodesy/ellipsoidalBaseDI.py +17 -15
  30. pygeodesy/ellipsoidalNvector.py +6 -3
  31. pygeodesy/ellipsoidalVincenty.py +4 -1
  32. pygeodesy/ellipsoids.py +186 -164
  33. pygeodesy/elliptic.py +9 -9
  34. pygeodesy/errors.py +44 -43
  35. pygeodesy/etm.py +7 -7
  36. pygeodesy/fmath.py +30 -14
  37. pygeodesy/formy.py +11 -12
  38. pygeodesy/frechet.py +216 -109
  39. pygeodesy/fstats.py +5 -4
  40. pygeodesy/fsums.py +79 -78
  41. pygeodesy/gars.py +4 -3
  42. pygeodesy/geodesici.py +15 -14
  43. pygeodesy/geodesicw.py +34 -32
  44. pygeodesy/geodesicx/__init__.py +1 -1
  45. pygeodesy/geodesicx/__main__.py +11 -9
  46. pygeodesy/geodesicx/gx.py +30 -33
  47. pygeodesy/geodesicx/gxarea.py +2 -2
  48. pygeodesy/geodesicx/gxline.py +5 -5
  49. pygeodesy/geodsolve.py +18 -17
  50. pygeodesy/geohash.py +5 -5
  51. pygeodesy/geoids.py +34 -31
  52. pygeodesy/hausdorff.py +17 -13
  53. pygeodesy/heights.py +2 -4
  54. pygeodesy/internals.py +28 -44
  55. pygeodesy/interns.py +10 -7
  56. pygeodesy/iters.py +8 -8
  57. pygeodesy/karney.py +68 -62
  58. pygeodesy/ktm.py +5 -5
  59. pygeodesy/latlonBase.py +20 -21
  60. pygeodesy/lazily.py +104 -78
  61. pygeodesy/lcc.py +11 -9
  62. pygeodesy/ltp.py +56 -58
  63. pygeodesy/ltpTuples.py +35 -36
  64. pygeodesy/mgrs.py +7 -6
  65. pygeodesy/named.py +48 -177
  66. pygeodesy/nvectorBase.py +7 -7
  67. pygeodesy/osgr.py +9 -8
  68. pygeodesy/points.py +12 -10
  69. pygeodesy/props.py +25 -25
  70. pygeodesy/resections.py +83 -80
  71. pygeodesy/rhumb/__init__.py +1 -1
  72. pygeodesy/rhumb/aux_.py +7 -7
  73. pygeodesy/rhumb/bases.py +22 -20
  74. pygeodesy/rhumb/ekx.py +6 -6
  75. pygeodesy/rhumb/solve.py +15 -15
  76. pygeodesy/solveBase.py +3 -3
  77. pygeodesy/sphericalBase.py +6 -6
  78. pygeodesy/sphericalNvector.py +6 -5
  79. pygeodesy/sphericalTrigonometry.py +8 -7
  80. pygeodesy/streprs.py +14 -14
  81. pygeodesy/trf.py +14 -12
  82. pygeodesy/triaxials.py +29 -26
  83. pygeodesy/units.py +5 -4
  84. pygeodesy/unitsBase.py +5 -4
  85. pygeodesy/ups.py +3 -3
  86. pygeodesy/utily.py +4 -4
  87. pygeodesy/utmups.py +4 -4
  88. pygeodesy/utmupsBase.py +110 -18
  89. pygeodesy/vector2d.py +20 -13
  90. pygeodesy/vector3d.py +7 -6
  91. pygeodesy/webmercator.py +6 -5
  92. pygeodesy/wgrs.py +6 -5
  93. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/METADATA +30 -25
  94. pygeodesy-25.5.5.dist-info/RECORD +119 -0
  95. pygeodesy-25.4.8.dist-info/RECORD +0 -118
  96. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/WHEEL +0 -0
  97. {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/top_level.txt +0 -0
pygeodesy/named.py CHANGED
@@ -13,32 +13,29 @@ standard Python C{namedtuple}s.
13
13
  @see: Module L{pygeodesy.namedTuples} for (most of) the C{Named-Tuples}.
14
14
  '''
15
15
 
16
- from pygeodesy.basics import isidentifier, iskeyword, isstr, itemsorted, len2, \
17
- _xcopy, _xdup, _xinstanceof, _xsubclassof, _zip
16
+ from pygeodesy.basics import isbool, isidentifier, iskeyword, isstr, itemsorted, \
17
+ len2, _xcopy, _xdup, _xinstanceof, _xsubclassof, _zip
18
18
  # from pygeodesy.ecef import EcefKarney # _MODS
19
19
  from pygeodesy.errors import _AssertionError, _AttributeError, _incompatible, \
20
20
  _IndexError, _KeyError, LenError, _NameError, \
21
21
  _NotImplementedError, _TypeError, _TypesError, \
22
22
  _UnexpectedError, UnitError, _ValueError, \
23
23
  _xattr, _xkwds, _xkwds_item2, _xkwds_pop2
24
- from pygeodesy.internals import _caller3, _DUNDER_nameof, _getPYGEODESY, _isPyPy, \
25
- _sizeof, _under
24
+ from pygeodesy.internals import _caller3, _envPYGEODESY, _isPyPy, _sizeof, \
25
+ typename, _under
26
26
  from pygeodesy.interns import MISSING, NN, _AT_, _COLON_, _COLONSPACE_, _COMMA_, \
27
- _COMMASPACE_, _doesn_t_exist_, _DOT_, _DUNDER_, \
28
- _DUNDER_name_, _EQUAL_, _exists_, _immutable_, _name_, \
29
- _NL_, _NN_, _no_, _other_, _s_, _SPACE_, _std_, \
30
- _UNDER_, _vs_
27
+ _COMMASPACE_, _DNAME_, _doesn_t_exist_, _DOT_, _DUNDER_, \
28
+ _EQUAL_, _exists_, _immutable_, _name_, _NL_, _NN_, \
29
+ _no_, _other_, _s_, _SPACE_, _std_, _UNDER_, _vs_
31
30
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
32
- # from pygeodesy.ltp import Ltp, _toLocal, _toLtp # _MODS
33
- # from pygeodesy.ltpTuples import Aer, Enu, Ned # _MODS
34
31
  from pygeodesy.props import _allPropertiesOf_n, deprecated_method, _hasProperty, \
35
32
  _update_all, property_doc_, Property_RO, property_RO, \
36
- _update_attrs, property_ROver
33
+ _update_attrs
37
34
  from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
38
35
  # from pygeodesy.units import _toUnit # _MODS
39
36
 
40
37
  __all__ = _ALL_LAZY.named
41
- __version__ = '24.12.05'
38
+ __version__ = '25.04.28'
42
39
 
43
40
  _COMMANL_ = _COMMA_ + _NL_
44
41
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
@@ -49,7 +46,7 @@ _MRO_ = 'MRO'
49
46
  _name = _under(_name_)
50
47
  _Names_ = '_Names_'
51
48
  _registered_ = 'registered' # PYCHOK used!
52
- _std_NotImplemented = _getPYGEODESY('NOTIMPLEMENTED', NN).lower() == _std_
49
+ _std_NotImplemented = _envPYGEODESY('NOTIMPLEMENTED', NN).lower() == _std_
53
50
  _such_ = 'such'
54
51
  _Units_ = '_Units_'
55
52
  _UP = 2
@@ -94,7 +91,7 @@ class ADict(dict):
94
91
  '''(INTERNAL) Create an C{AttributeError}.
95
92
  '''
96
93
  if _DOT_ not in name: # NOT classname(self)!
97
- name = _DOT_(self.__class__.__name__, name)
94
+ name = _DOT_(self.typename, name)
98
95
  return _AttributeError(item=name, txt=_doesn_t_exist_)
99
96
 
100
97
  @property_RO
@@ -116,11 +113,16 @@ class ADict(dict):
116
113
  dict.update(self, items)
117
114
  return self # in RhumbLineBase.Intersecant2, _PseudoRhumbLine.Position
118
115
 
116
+ def _toL(self):
117
+ '''(INTERNAL) Get items as list.
118
+ '''
119
+ return list(_EQUAL_(*t) for t in self.items()) # _kwdstr
120
+
119
121
  def toRepr(self, **prec_fmt):
120
122
  '''Like C{repr(dict)} but with C{name} prefix and with
121
123
  C{floats} formatted by function L{pygeodesy.fstr}.
122
124
  '''
123
- n = _xattr(self, name=NN) or self.__class__.__name__
125
+ n = _xattr(self, name=NN) or self.typename
124
126
  return Fmt.PAREN(n, self._toT(_EQUAL_, **prec_fmt))
125
127
 
126
128
  def toStr(self, **prec_fmt):
@@ -135,6 +137,12 @@ class ADict(dict):
135
137
  kwds = _xkwds(kwds, prec=6, fmt=Fmt.F, sep=sep)
136
138
  return _COMMASPACE_.join(pairs(itemsorted(self), **kwds))
137
139
 
140
+ @property_RO
141
+ def typename(self):
142
+ '''Get this C{ADict}'s type name (C{str}).
143
+ '''
144
+ return type(self).__name__ # typename(type(self))
145
+
138
146
 
139
147
  class _Named(object):
140
148
  '''(INTERNAL) Root class for named objects.
@@ -294,7 +302,7 @@ class _Named(object):
294
302
 
295
303
  @arg which: The method (C{callable}).
296
304
  '''
297
- return _DOT_(self.classname, which.__name__ if callable(which) else _NN_)
305
+ return _DOT_(self.classname, typename(which) if callable(which) else _NN_)
298
306
 
299
307
  @property_doc_(''' the name (C{str}).''')
300
308
  def name(self):
@@ -314,7 +322,7 @@ class _Named(object):
314
322
  elif n != m:
315
323
  n = repr(n)
316
324
  c = self.classname
317
- t = _DOT_(c, Fmt.PAREN(self.rename.__name__, n))
325
+ t = _DOT_(c, Fmt.PAREN(typename(self.rename), n))
318
326
  n = _DOT_(c, Fmt.EQUALSPACED(name=n))
319
327
  m = Fmt.PAREN(_SPACE_('was', repr(m)))
320
328
  n = _SPACE_(n, m)
@@ -362,7 +370,7 @@ class _Named(object):
362
370
  def named4(self):
363
371
  '''Get the C{package.module.class} name I{and/or} the name or C{""} (C{str}).
364
372
  '''
365
- return _xjoined_(_DOT_(self.__module__, self.__class__.__name__), self.name)
373
+ return _xjoined_(_DOT_(self.__module__, self.typename), self.name)
366
374
 
367
375
  def _notImplemented(self, *args, **kwds):
368
376
  '''(INTERNAL) See function L{notImplemented}.
@@ -426,6 +434,12 @@ class _Named(object):
426
434
  # '''
427
435
  # return _DOT_(self, unstr(which, *args, **kwds))
428
436
 
437
+ @property_RO
438
+ def typename(self):
439
+ '''Get this object's type name (C{str}).
440
+ '''
441
+ return type(self).__name__ # typename(type(self))
442
+
429
443
  def _xnamed(self, inst, name=NN, **force):
430
444
  '''(INTERNAL) Set the instance' C{.name = self.name}.
431
445
 
@@ -586,7 +600,7 @@ class _NamedDict(ADict, _Named):
586
600
  def _KeyError(self, key, *value): # PYCHOK no cover
587
601
  '''(INTERNAL) Create a C{KeyError}.
588
602
  '''
589
- n = self.name or self.__class__.__name__
603
+ n = self.name or self.typename
590
604
  t = Fmt.SQUARE(n, key)
591
605
  if value:
592
606
  t = Fmt.EQUALSPACED(t, *value)
@@ -622,7 +636,7 @@ class _NamedEnum(_NamedDict):
622
636
  @arg Classes: Additional, acceptable classes or C{type}s.
623
637
  '''
624
638
  self._item_Classes = (Class,) + Classes
625
- n = _name__(**name) or NN(Class.__name__, _s_) # _DUNDER_nameof
639
+ n = _name__(**name) or NN(typename(Class), _s_)
626
640
  if n and _xvalid(n, underOK=True):
627
641
  _Named.name.fset(self, n) # see _Named.name
628
642
 
@@ -695,7 +709,7 @@ class _NamedEnum(_NamedDict):
695
709
  '''
696
710
  if all: # instantiate any remaining L{_LazyNamedEnumItem}
697
711
  _isa = isinstance
698
- for n, p in tuple(self.__class__.__dict__.items()):
712
+ for n, p in tuple(type(self).__dict__.items()):
699
713
  if _isa(p, _LazyNamedEnumItem):
700
714
  _ = getattr(self, n)
701
715
  return itemsorted(self) if asorted else ADict.items(self)
@@ -731,7 +745,7 @@ class _NamedEnum(_NamedDict):
731
745
  '''
732
746
  if item is all or item is any:
733
747
  _ = self.items(all=True)
734
- n = item.__name__
748
+ n = typename(item)
735
749
  else:
736
750
  try:
737
751
  n = item.name
@@ -899,148 +913,6 @@ class _NamedEnumItem(_NamedBase):
899
913
  raise _AssertionError(t)
900
914
 
901
915
 
902
- class _NamedLocal(object):
903
- '''(INTERNAL) Base class for C{CartesianBase}, C{Ecef9Tuple} and C{LatLonBase}.
904
- '''
905
-
906
- @property_ROver
907
- def Ecef(self):
908
- '''Get the ECEF I{class} (L{EcefKarney}), I{once}.
909
- '''
910
- return _MODS.ecef.EcefKarney
911
-
912
- @property_RO
913
- def _ecef9(self):
914
- '''I{Must be overloaded}.'''
915
- notOverloaded(self)
916
-
917
- @Property_RO
918
- def _Ltp(self):
919
- '''(INTERNAL) Cache this instance' LTP (L{Ltp}).
920
- '''
921
- return self._ltp.Ltp(self._ecef9, ecef=self.Ecef(self.datum), name=self.name)
922
-
923
- @property_ROver
924
- def _ltp(self):
925
- '''(INTERNAL) Get module L{pygeodesy.ltp}, I{once}.
926
- '''
927
- return _MODS.ltp
928
-
929
- def _ltp_toLocal(self, ltp, Xyz_kwds, **Xyz): # overloaded in C{Ecef9Tuple}
930
- '''(INTERNAL) Invoke C{ltp._toLocal}.
931
- '''
932
- Xyz_ = self._ltp_toLocal2(Xyz_kwds, **Xyz)
933
- return self._ltp._toLocal(self, ltp, *Xyz_) # self._ecef9
934
-
935
- def _ltp_toLocal2(self, Xyz_kwds, _None=None, **Xyz):
936
- '''(INTERNAL) Return 2-tuple C{(Xyz_Class, Xyz_kwds)}.
937
- '''
938
- C, _ = Xyz_ = _xkwds_pop2(Xyz_kwds, **Xyz)
939
- if C is not _None: # validate C
940
- n, X = _xkwds_item2(Xyz)
941
- if X is not C:
942
- _xsubclassof(X, **{n: C})
943
- return Xyz_
944
-
945
- @property_ROver
946
- def _ltpTuples(self):
947
- '''(INTERNAL) Get module L{pygeodesy.ltpTuples}, I{once}.
948
- '''
949
- return _MODS.ltpTuples
950
-
951
- def toAer(self, ltp=None, **Aer_and_kwds):
952
- '''Convert this instance to I{local} I{Azimuth, Elevation, slant Range} (AER) components.
953
-
954
- @kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
955
- instance' L{LTP<pygeodesy.named._NamedLocal.toLtp>}.
956
- @kwarg Aer_and_kwds: Optional AER class C{B{Aer}=}L{Aer<pygeodesy.ltpTuples.Aer>}
957
- to use and optionally, additional B{C{Aer}} keyword arguments.
958
-
959
- @return: An B{C{Aer}} instance.
960
-
961
- @raise TypeError: Invalid B{C{ltp}}.
962
-
963
- @see: Method L{toLocal<pygeodesy.named._NamedLocal.toLocal>}.
964
- '''
965
- return self._ltp_toLocal(ltp, Aer_and_kwds, Aer=self._ltpTuples.Aer)
966
-
967
- def toEnu(self, ltp=None, **Enu_and_kwds):
968
- '''Convert this instance to I{local} I{East, North, Up} (ENU) components.
969
-
970
- @kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
971
- instance' L{LTP<pygeodesy.named._NamedLocal.toLtp>}.
972
- @kwarg Enu_and_kwds: Optional ENU class C{B{Enu}=}L{Enu<pygeodesy.ltpTuples.Enu>}
973
- to use and optionally, additional B{C{Enu}} keyword arguments.
974
-
975
- @return: An B{C{Enu}} instance.
976
-
977
- @raise TypeError: Invalid B{C{ltp}}.
978
-
979
- @see: Method L{toLocal<pygeodesy.named._NamedLocal.toLocal>}.
980
- '''
981
- return self._ltp_toLocal(ltp, Enu_and_kwds, Enu=self._ltpTuples.Enu)
982
-
983
- def toLocal(self, Xyz=None, ltp=None, **Xyz_kwds):
984
- '''Convert this instance to I{local} components in a I{local tangent plane} (LTP)
985
-
986
- @kwarg Xyz: Optional I{local} components class (L{XyzLocal}, L{Aer},
987
- L{Enu}, L{Ned}) or C{None}.
988
- @kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
989
- cartesian's L{LTP<pygeodesy.named._NamedLocal.toLtp>}.
990
- @kwarg Xyz_kwds: Optionally, additional B{C{Xyz}} keyword arguments, ignored
991
- if C{B{Xyz} is None}.
992
-
993
- @return: An B{C{Xyz}} instance or a L{Local9Tuple}C{(x, y, z, lat, lon,
994
- height, ltp, ecef, M)} if C{B{Xyz} is None} (with C{M=None}).
995
-
996
- @raise TypeError: Invalid B{C{ltp}}.
997
- '''
998
- return self._ltp_toLocal(ltp, Xyz_kwds, Xyz=Xyz, _None=Xyz)
999
-
1000
- def toLtp(self, Ecef=None, **name):
1001
- '''Return the I{local tangent plane} (LTP) for this instance.
1002
-
1003
- @kwarg Ecef: Optional ECEF I{class} (L{EcefKarney}, ... L{EcefYou}), overriding
1004
- this instance' L{Ecef<pygeodesy.named._NamedLocal.Ecef>}.
1005
- @kwarg name: Optional C{B{name}=NN} (C{str}).
1006
-
1007
- @return: An B{C{Ltp}} instance.
1008
- '''
1009
- return self._ltp._toLtp(self, Ecef, self._ecef9, name) # needs self.Ecef and self._Ltp
1010
-
1011
- def toNed(self, ltp=None, **Ned_and_kwds):
1012
- '''Convert this instance to I{local} I{North, East, Down} (NED) components.
1013
-
1014
- @kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
1015
- instance' L{LTP<pygeodesy.named._NamedLocal.toLtp>}.
1016
- @kwarg Ned_and_kwds: Optional NED class C{B{Ned}=}L{Ned<pygeodesy.ltpTuples.Ned>}
1017
- to use and optionally, additional B{C{Ned}} keyword arguments.
1018
-
1019
- @return: An B{C{Ned}} instance.
1020
-
1021
- @raise TypeError: Invalid B{C{ltp}}.
1022
-
1023
- @see: Method L{toLocal<pygeodesy.named._NamedLocal.toLocal>}.
1024
- '''
1025
- return self._ltp_toLocal(ltp, Ned_and_kwds, Ned=self._ltpTuples.Ned)
1026
-
1027
- def toXyz(self, ltp=None, **Xyz_and_kwds):
1028
- '''Convert this instance to I{local} I{X, Y, Z} (XYZ) components.
1029
-
1030
- @kwarg ltp: The I{local tangent plane} (LTP) to use (L{Ltp}), overriding this
1031
- instance' L{LTP<pygeodesy.named._NamedLocal.toLtp>}.
1032
- @kwarg Xyz_and_kwds: Optional XYZ class C{B{Xyz}=}L{Xyz<pygeodesy.ltpTuples.XyzLocal>}
1033
- to use and optionally, additional B{C{Xyz}} keyword arguments.
1034
-
1035
- @return: An B{C{Xyz}} instance.
1036
-
1037
- @raise TypeError: Invalid B{C{ltp}}.
1038
-
1039
- @see: Method L{toLocal<pygeodesy.named._NamedLocal.toLocal>}.
1040
- '''
1041
- return self._ltp_toLocal(ltp, Xyz_and_kwds, Xyz=self._ltpTuples.XyzLocal)
1042
-
1043
-
1044
916
  # from pygeodesy.props import _NamedProperty
1045
917
 
1046
918
 
@@ -1288,7 +1160,7 @@ class _NamedTuple(tuple, _Named):
1288
1160
  t = Fmt.SQUARE(_Units_=i) # PYCHOK no cover
1289
1161
  raise _TypeError(self._DOT_(t), u)
1290
1162
 
1291
- self.__class__._validated = True
1163
+ type(self)._validated = True
1292
1164
 
1293
1165
  def _xtend(self, xTuple, *items, **name):
1294
1166
  '''(INTERNAL) Extend this C{Named-Tuple} with C{items} to an other B{C{xTuple}}.
@@ -1297,7 +1169,7 @@ class _NamedTuple(tuple, _Named):
1297
1169
  if len(xTuple._Names_) != (len(self._Names_) + len(items)) or \
1298
1170
  xTuple._Names_[:len(self)] != self._Names_: # PYCHOK no cover
1299
1171
  c = NN(self.classname, repr(self._Names_))
1300
- x = NN(xTuple.__name__, repr(xTuple._Names_))
1172
+ x = NN(typename(xTuple), repr(xTuple._Names_))
1301
1173
  raise TypeError(_SPACE_(c, _vs_, x))
1302
1174
  t = self + items
1303
1175
  return xTuple(t, name=self._name__(name)) # .reUnit(*self._Units_)
@@ -1357,7 +1229,7 @@ def classname(inst, prefixed=None):
1357
1229
  @return: The B{C{inst}}'s C{[module.]class} name (C{str}).
1358
1230
  '''
1359
1231
  if prefixed is None:
1360
- prefixed = getattr(inst, classnaming.__name__, prefixed)
1232
+ prefixed = getattr(inst, typename(classnaming), prefixed)
1361
1233
  return modulename(inst.__class__, prefixed=prefixed)
1362
1234
 
1363
1235
 
@@ -1369,7 +1241,7 @@ def classnaming(prefixed=None):
1369
1241
  @return: Previous class naming setting (C{bool}).
1370
1242
  '''
1371
1243
  t = _Named._classnaming
1372
- if prefixed in (True, False):
1244
+ if isbool(prefixed):
1373
1245
  _Named._classnaming = prefixed
1374
1246
  return t
1375
1247
 
@@ -1385,9 +1257,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1385
1257
  @return: The B{C{class}}'s C{[module.]class} name (C{str}).
1386
1258
  '''
1387
1259
  try:
1388
- n = clas.__name__
1260
+ n = typename(clas)
1389
1261
  except AttributeError:
1390
- n = clas if isstr(clas) else _DUNDER_name_
1262
+ n = clas if isstr(clas) else _DNAME_
1391
1263
  if prefixed or (classnaming() if prefixed is None else False):
1392
1264
  try:
1393
1265
  m = clas.__module__.rsplit(_DOT_, 1)
@@ -1406,7 +1278,7 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1406
1278
  # if name: # is given
1407
1279
  # n = _name__(**name) if isinstance(name, dict) else str(name)
1408
1280
  # elif name__ is not None:
1409
- # n = getattr(name__, _DUNDER_name_, NN) # _xattr(name__, __name__=NN)
1281
+ # n = getattr(name__, _DNAME_, NN) # _xattr(name__, __name__=NN)
1410
1282
  # else:
1411
1283
  # n = name # NN or None or {} or any False type
1412
1284
  # if _or_nameof is not None and not n:
@@ -1443,7 +1315,7 @@ def _name2__(name=NN, name__=None, _or_nameof=None, **kwds):
1443
1315
  else:
1444
1316
  n = str(name)
1445
1317
  elif name__ is not None:
1446
- n = _DUNDER_nameof(name__, NN)
1318
+ n = typename(name__, NN)
1447
1319
  else:
1448
1320
  n = name if name is None else NN
1449
1321
  if _or_nameof is not None and not n:
@@ -1461,7 +1333,7 @@ def nameof(inst):
1461
1333
  n = _xattr(inst, name=NN)
1462
1334
  if not n: # and isinstance(inst, property):
1463
1335
  try:
1464
- n = inst.fget.__name__
1336
+ n = typename(inst.fget)
1465
1337
  except AttributeError:
1466
1338
  n = NN
1467
1339
  return n
@@ -1470,7 +1342,7 @@ def nameof(inst):
1470
1342
  def _notDecap(where):
1471
1343
  '''De-Capitalize C{where.__name__}.
1472
1344
  '''
1473
- n = where.__name__
1345
+ n = typename(where)
1474
1346
  c = n[3].lower() # len(_not_)
1475
1347
  return NN(n[:3], _SPACE_, c, n[4:])
1476
1348
 
@@ -1478,8 +1350,8 @@ def _notDecap(where):
1478
1350
  def _notError(inst, name, args, kwds): # PYCHOK no cover
1479
1351
  '''(INTERNAL) Format an error message.
1480
1352
  '''
1481
- n = _DOT_(classname(inst, prefixed=True), _DUNDER_nameof(name, name))
1482
- m = _COMMASPACE_.join(modulename(c, prefixed=True) for c in inst.__class__.__mro__[1:-1])
1353
+ n = _DOT_(classname(inst, prefixed=True), typename(name, name))
1354
+ m = _COMMASPACE_.join(modulename(c, prefixed=True) for c in type(inst).__mro__[1:-1])
1483
1355
  return _COMMASPACE_(unstr(n, *args, **kwds), Fmt.PAREN(_MRO_, m))
1484
1356
 
1485
1357
 
@@ -1595,7 +1467,6 @@ def _xvalid(name, underOK=False):
1595
1467
  __all__ += _ALL_DOCS(_Named,
1596
1468
  _NamedBase, # _NamedDict,
1597
1469
  _NamedEnum, _NamedEnumItem,
1598
- _NamedLocal,
1599
1470
  _NamedTuple)
1600
1471
 
1601
1472
  # **) MIT License
pygeodesy/nvectorBase.py CHANGED
@@ -10,7 +10,7 @@ and published under the same MIT Licence**, see U{Vector-based geodesy
10
10
  <https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>}.
11
11
  '''
12
12
 
13
- # from pygeodesy.basics import map1 # from .namedTuples
13
+ from pygeodesy.basics import _isin, map1
14
14
  from pygeodesy.constants import EPS, EPS0, EPS1, EPS_2, R_M, \
15
15
  _0_0, _1_0, _2_0, _N_2_0
16
16
  # from pygeodesy.datums import _spherical_datum # from .formy
@@ -27,7 +27,7 @@ from pygeodesy.latlonBase import LatLonBase, _ALL_DOCS, _ALL_LAZY, _MODS
27
27
  # from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS # from .latlonBase
28
28
  from pygeodesy.named import _xother3, _under
29
29
  from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Trilaterate5Tuple, \
30
- Vector3Tuple, Vector4Tuple, map1
30
+ Vector3Tuple, Vector4Tuple
31
31
  from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
32
32
  property_RO, property_ROnce, _update_all
33
33
  from pygeodesy.streprs import Fmt, hstr, unstr
@@ -38,7 +38,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
38
38
  from math import degrees, fabs, sqrt
39
39
 
40
40
  __all__ = _ALL_LAZY.nvectorBase
41
- __version__ = '24.11.24'
41
+ __version__ = '25.04.14'
42
42
 
43
43
 
44
44
  class NvectorBase(Vector3d): # XXX kept private
@@ -217,7 +217,7 @@ class NvectorBase(Vector3d): # XXX kept private
217
217
  @deprecated_method
218
218
  def to3abh(self, height=None): # PYCHOK no cover
219
219
  '''DEPRECATED, use property L{philamheight} or C{philam.to3Tuple(B{height})}.'''
220
- return self.philamheight if height in (None, self.h) else \
220
+ return self.philamheight if _isin(height, None, self.h) else \
221
221
  self.philam.to3Tuple(height)
222
222
 
223
223
  def toCartesian(self, h=None, Cartesian=None, datum=None, **name_Cartesian_kwds): # PYCHOK signature
@@ -249,7 +249,7 @@ class NvectorBase(Vector3d): # XXX kept private
249
249
  def _toEcefDrv3(self, CC, LL, datum, h, name=NN, **unused):
250
250
  '''(INTERNAL) Helper for methods C{toCartesian} and C{toLatLon}.
251
251
  '''
252
- D = self.datum if datum in (None, self.datum) else \
252
+ D = self.datum if _isin(datum, None, self.datum) else \
253
253
  _spherical_datum(datum, name=self.name)
254
254
  if LL is None:
255
255
  v = Vector3d(self, name=name or self.name) # .toVector3d(norm=False)
@@ -272,7 +272,7 @@ class NvectorBase(Vector3d): # XXX kept private
272
272
  @deprecated_method
273
273
  def to3llh(self, height=None): # PYCHOK no cover
274
274
  '''DEPRECATED, use property C{latlonheight} or C{latlon.to3Tuple(B{height})}.'''
275
- return self.latlonheight if height in (None, self.h) else \
275
+ return self.latlonheight if _isin(height, None, self.h) else \
276
276
  self.latlon.to3Tuple(height)
277
277
 
278
278
  def toLatLon(self, height=None, LatLon=None, datum=None, **name_LatLon_kwds):
@@ -336,7 +336,7 @@ class NvectorBase(Vector3d): # XXX kept private
336
336
  @deprecated_method
337
337
  def to4xyzh(self, h=None): # PYCHOK no cover
338
338
  '''DEPRECATED, use property L{xyzh} or C{xyz.to4Tuple(B{h})}.'''
339
- return self.xyzh if h in (None, self.h) else Vector4Tuple(
339
+ return self.xyzh if _isin(h, None, self.h) else Vector4Tuple(
340
340
  self.x, self.y, self.z, h, name=self.name)
341
341
 
342
342
  def unit(self, ll=None):
pygeodesy/osgr.py CHANGED
@@ -27,7 +27,7 @@ and U{Ordnance Survey National Grid<https://WikiPedia.org/wiki/Ordnance_Survey_N
27
27
  from __future__ import division as _; del _ # PYCHOK semicolon
28
28
 
29
29
  from pygeodesy.basics import halfs2, isbool, isfloat, map1, \
30
- _splituple, _xsubclassof
30
+ _splituple, _xsubclassof, typename
31
31
  from pygeodesy.constants import _1_0, _10_0, _N_2_0 # PYCHOK used!
32
32
  from pygeodesy.datums import Datums, _ellipsoidal_datum, _WGS84
33
33
  # from pygeodesy.dms import parseDMS2 # _MODS
@@ -36,9 +36,10 @@ from pygeodesy.errors import _parseX, _TypeError, _ValueError, \
36
36
  _xkwds, _xkwds_get, _xkwds_pop2
37
37
  from pygeodesy.fmath import Fdot, fpowers
38
38
  from pygeodesy.fsums import _Fsumf_
39
+ # from pygeodesy.internals import typename # from .basics
39
40
  from pygeodesy.interns import MISSING, NN, _A_, _COLON_, _COMMA_, \
40
- _COMMASPACE_, _DOT_, _ellipsoidal_, \
41
- _latlon_, _not_, _SPACE_
41
+ _COMMASPACE_, _DMAIN_, _DOT_, _not_, \
42
+ _ellipsoidal_, _latlon_, _SPACE_
42
43
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
43
44
  from pygeodesy.named import _name2__, _NamedBase, nameof
44
45
  from pygeodesy.namedTuples import EasNor2Tuple, LatLon2Tuple, \
@@ -53,7 +54,7 @@ from pygeodesy.utily import degrees90, degrees180, sincostan3, truncate
53
54
  from math import cos, fabs, radians, sin, sqrt
54
55
 
55
56
  __all__ = _ALL_LAZY.osgr
56
- __version__ = '24.11.06'
57
+ __version__ = '25.04.12'
57
58
 
58
59
  _equivalent_ = 'equivalent'
59
60
  _OSGR_ = 'OSGR'
@@ -336,7 +337,7 @@ class Osgr(_NamedBase):
336
337
  else: # PYCHOK no cover
337
338
  t = str(self)
338
339
  t = Fmt.PAREN(self.classname, repr(t))
339
- t = _DOT_(t, self.toLatLon.__name__)
340
+ t = _DOT_(t, typename(self.toLatLon))
340
341
  t = unstr(t, eps=eps, kTM=kTM)
341
342
  raise OSGRError(Fmt.no_convergence(m), txt=t)
342
343
 
@@ -493,11 +494,11 @@ def _ll2LatLon3(ll, LatLon, datum, LatLon_kwds):
493
494
  '''
494
495
  n = nameof(ll)
495
496
  if LatLon is None:
496
- r = _ll2datum(ll, datum, LatLonDatum3Tuple.__name__)
497
+ r = _ll2datum(ll, datum, typename(LatLonDatum3Tuple))
497
498
  r = LatLonDatum3Tuple(r.lat, r.lon, r.datum, name=n)
498
499
  else: # must be ellipsoidal
499
500
  _xsubclassof(_LLEB, LatLon=LatLon)
500
- r = _ll2datum(ll, datum, LatLon.__name__)
501
+ r = _ll2datum(ll, datum, typename(LatLon))
501
502
  r = LatLon(r.lat, r.lon, datum=r.datum, **_xkwds(LatLon_kwds, name=n))
502
503
  if r._iteration != ll._iteration:
503
504
  r._iteration = ll._iteration
@@ -670,7 +671,7 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, # MCCABE 14
670
671
  return r
671
672
 
672
673
 
673
- if __name__ == '__main__':
674
+ if __name__ == _DMAIN_:
674
675
 
675
676
  from pygeodesy import printf
676
677
  from random import random, seed
pygeodesy/points.py CHANGED
@@ -27,7 +27,7 @@ C{ilon} longitude index in each 2+tuple.
27
27
 
28
28
  from pygeodesy.basics import isclass, isint, isscalar, issequence, \
29
29
  _xdup, issubclassof, _Sequence, _xcopy, \
30
- _xinstanceof
30
+ _xinstanceof, typename
31
31
  from pygeodesy.constants import EPS, EPS1, PI_2, R_M, isnear0, isnear1, \
32
32
  _umod_360, _0_0, _0_5, _1_0, _2_0, _6_0, \
33
33
  _90_0, _N_90_0, _180_0, _360_0
@@ -39,6 +39,7 @@ from pygeodesy.errors import CrossError, crosserrors, _IndexError, \
39
39
  from pygeodesy.fmath import favg, fdot, hypot, Fsum, fsum
40
40
  # from pygeodesy.fsums import Fsum, fsum # from .fmath
41
41
  from pygeodesy.formy import _bearingTo2, equirectangular4, _spherical_datum
42
+ # from pygeodesy.internals import typename # from .basics
42
43
  from pygeodesy.interns import NN, _colinear_, _COMMASPACE_, _composite_, \
43
44
  _DEQUALSPACED_, _ELLIPSIS_, _EW_, _immutable_, \
44
45
  _near_, _no_, _NS_, _point_, _SPACE_, _UNDER_, \
@@ -62,7 +63,7 @@ from pygeodesy.utily import atan2b, degrees90, degrees180, degrees2m, \
62
63
  from math import cos, fabs, fmod as _fmod, radians, sin
63
64
 
64
65
  __all__ = _ALL_LAZY.points
65
- __version__ = '24.10.24'
66
+ __version__ = '25.04.18'
66
67
 
67
68
  _ilat_ = 'ilat'
68
69
  _ilon_ = 'ilon'
@@ -164,7 +165,7 @@ class LatLon_(LatLonBase): # XXX in heights._HeightBase.height
164
165
  favg(self.height, r.height, f=f)
165
166
  # = self._havg(r, f=f, h=height)
166
167
  r = self.classof(lat, lon, height=h, datum=r.datum,
167
- name=r.intermediateTo.__name__)
168
+ name=typename(r.intermediateTo))
168
169
  return r
169
170
 
170
171
  def toRepr(self, **kwds):
@@ -1085,8 +1086,8 @@ def _distanceTo(Error, **name_points): # .frechet, .hausdorff, .heights
1085
1086
  name, ps = _xkwds_item2(name_points)
1086
1087
  for i, p in enumerate(ps):
1087
1088
  if not callable(_xattr(p, distanceTo=None)):
1088
- n = _distanceTo.__name__[1:]
1089
- t = _SPACE_(_no_, callable.__name__, n)
1089
+ n = typename(_distanceTo)[1:]
1090
+ t = _SPACE_(_no_, typename(callable), n)
1090
1091
  raise Error(Fmt.SQUARE(name, i), p, txt=t)
1091
1092
  return ps
1092
1093
 
@@ -1159,7 +1160,7 @@ def fractional(points, fi, j=None, wrap=None, LatLon=None, Vector=None, **kwds):
1159
1160
  raise _TypeError(txt__=fractional, **kwds)
1160
1161
  w = wrap if LatLon else False # intermediateTo
1161
1162
  try:
1162
- if not isscalar(fi) or fi < 0:
1163
+ if (not isscalar(fi)) or fi < 0:
1163
1164
  raise IndexError
1164
1165
  n = _xattr(fi, fin=0)
1165
1166
  p = _fractional(points, fi, j, fin=n, wrap=w) # see .units.FIx
@@ -1172,7 +1173,7 @@ def fractional(points, fi, j=None, wrap=None, LatLon=None, Vector=None, **kwds):
1172
1173
  return p
1173
1174
 
1174
1175
 
1175
- def _fractional(points, fi, j, fin=None, wrap=None): # in .frechet.py
1176
+ def _fractional(points, fi, j, fin=None, wrap=None, dup=False): # in .frechet.py
1176
1177
  '''(INTERNAL) Compute point at L{fractional} index C{fi} and C{j}.
1177
1178
  '''
1178
1179
  i = int(fi)
@@ -1186,12 +1187,13 @@ def _fractional(points, fi, j, fin=None, wrap=None): # in .frechet.py
1186
1187
  q = points[j]
1187
1188
  if r >= EPS1: # PYCHOK no cover
1188
1189
  p = q
1189
- elif wrap is not None: # in (True, False)
1190
+ elif wrap is not None: # isbool(wrap)
1190
1191
  p = p.intermediateTo(q, r, wrap=wrap)
1191
1192
  elif _isLatLon(p): # backward compatible default
1192
- p = LatLon2Tuple(favg(p.lat, q.lat, f=r),
1193
+ t = LatLon2Tuple(favg(p.lat, q.lat, f=r),
1193
1194
  favg(p.lon, q.lon, f=r),
1194
1195
  name__=fractional)
1196
+ p = p.dup(lat=t.lat, lon=t.lon, name=t.name) if dup else t # PYCHOK lat, lon
1195
1197
  else: # assume p and q are cartesian or vectorial
1196
1198
  z = p.z if p.z is q.z else favg(p.z, q.z, f=r)
1197
1199
  p = Vector3Tuple(favg(p.x, q.x, f=r),
@@ -1573,7 +1575,7 @@ def nearestOn5(point, points, closed=False, wrap=False, adjust=True,
1573
1575
  a = atan2b(dx, dy) # azimuth
1574
1576
  d = hypot( dx, dy)
1575
1577
  h = _h(c)
1576
- n = nameof(point) or nearestOn5.__name__
1578
+ n = nameof(point) or typename(nearestOn5)
1577
1579
  if LatLon_and_kwds:
1578
1580
  LL, kwds = _xkwds_pop2(LatLon_and_kwds, LatLon=None)
1579
1581
  if LL is not None: