pygeodesy 25.4.8__py2.py3-none-any.whl → 25.4.25__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. pygeodesy/__init__.py +30 -27
  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 +31 -17
  15. pygeodesy/booleans.py +12 -10
  16. pygeodesy/cartesianBase.py +21 -20
  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 +10 -7
  26. pygeodesy/elevations.py +9 -8
  27. pygeodesy/ellipsoidalBase.py +19 -8
  28. pygeodesy/ellipsoidalBaseDI.py +17 -15
  29. pygeodesy/ellipsoidalNvector.py +6 -3
  30. pygeodesy/ellipsoidalVincenty.py +4 -1
  31. pygeodesy/ellipsoids.py +167 -138
  32. pygeodesy/elliptic.py +9 -9
  33. pygeodesy/errors.py +44 -43
  34. pygeodesy/etm.py +7 -7
  35. pygeodesy/fmath.py +10 -9
  36. pygeodesy/formy.py +11 -12
  37. pygeodesy/frechet.py +216 -109
  38. pygeodesy/fstats.py +5 -4
  39. pygeodesy/fsums.py +78 -77
  40. pygeodesy/gars.py +4 -3
  41. pygeodesy/geodesici.py +15 -14
  42. pygeodesy/geodesicw.py +34 -32
  43. pygeodesy/geodesicx/__init__.py +1 -1
  44. pygeodesy/geodesicx/__main__.py +11 -9
  45. pygeodesy/geodesicx/gx.py +30 -33
  46. pygeodesy/geodesicx/gxarea.py +2 -2
  47. pygeodesy/geodesicx/gxline.py +5 -5
  48. pygeodesy/geodsolve.py +18 -17
  49. pygeodesy/geohash.py +5 -5
  50. pygeodesy/geoids.py +34 -31
  51. pygeodesy/hausdorff.py +17 -13
  52. pygeodesy/heights.py +2 -4
  53. pygeodesy/internals.py +28 -44
  54. pygeodesy/interns.py +10 -7
  55. pygeodesy/iters.py +8 -8
  56. pygeodesy/karney.py +68 -62
  57. pygeodesy/ktm.py +5 -5
  58. pygeodesy/latlonBase.py +14 -18
  59. pygeodesy/lazily.py +65 -63
  60. pygeodesy/lcc.py +11 -9
  61. pygeodesy/ltp.py +8 -7
  62. pygeodesy/ltpTuples.py +2 -2
  63. pygeodesy/mgrs.py +7 -6
  64. pygeodesy/named.py +47 -31
  65. pygeodesy/nvectorBase.py +7 -7
  66. pygeodesy/osgr.py +9 -8
  67. pygeodesy/points.py +12 -10
  68. pygeodesy/props.py +25 -25
  69. pygeodesy/resections.py +11 -10
  70. pygeodesy/rhumb/__init__.py +1 -1
  71. pygeodesy/rhumb/aux_.py +7 -7
  72. pygeodesy/rhumb/bases.py +22 -20
  73. pygeodesy/rhumb/ekx.py +6 -6
  74. pygeodesy/rhumb/solve.py +15 -15
  75. pygeodesy/solveBase.py +3 -3
  76. pygeodesy/sphericalBase.py +6 -6
  77. pygeodesy/sphericalNvector.py +6 -5
  78. pygeodesy/sphericalTrigonometry.py +8 -7
  79. pygeodesy/streprs.py +14 -14
  80. pygeodesy/trf.py +14 -12
  81. pygeodesy/triaxials.py +29 -26
  82. pygeodesy/units.py +5 -4
  83. pygeodesy/unitsBase.py +5 -4
  84. pygeodesy/ups.py +3 -3
  85. pygeodesy/utily.py +4 -4
  86. pygeodesy/utmups.py +4 -4
  87. pygeodesy/utmupsBase.py +88 -18
  88. pygeodesy/vector2d.py +18 -11
  89. pygeodesy/vector3d.py +7 -6
  90. pygeodesy/webmercator.py +6 -5
  91. pygeodesy/wgrs.py +6 -5
  92. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +27 -23
  93. pygeodesy-25.4.25.dist-info/RECORD +118 -0
  94. pygeodesy-25.4.8.dist-info/RECORD +0 -118
  95. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
  96. {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/named.py CHANGED
@@ -13,21 +13,20 @@ 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
31
  # from pygeodesy.ltp import Ltp, _toLocal, _toLtp # _MODS
33
32
  # from pygeodesy.ltpTuples import Aer, Enu, Ned # _MODS
@@ -38,7 +37,7 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
38
37
  # from pygeodesy.units import _toUnit # _MODS
39
38
 
40
39
  __all__ = _ALL_LAZY.named
41
- __version__ = '24.12.05'
40
+ __version__ = '25.04.14'
42
41
 
43
42
  _COMMANL_ = _COMMA_ + _NL_
44
43
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
@@ -49,7 +48,7 @@ _MRO_ = 'MRO'
49
48
  _name = _under(_name_)
50
49
  _Names_ = '_Names_'
51
50
  _registered_ = 'registered' # PYCHOK used!
52
- _std_NotImplemented = _getPYGEODESY('NOTIMPLEMENTED', NN).lower() == _std_
51
+ _std_NotImplemented = _envPYGEODESY('NOTIMPLEMENTED', NN).lower() == _std_
53
52
  _such_ = 'such'
54
53
  _Units_ = '_Units_'
55
54
  _UP = 2
@@ -94,7 +93,7 @@ class ADict(dict):
94
93
  '''(INTERNAL) Create an C{AttributeError}.
95
94
  '''
96
95
  if _DOT_ not in name: # NOT classname(self)!
97
- name = _DOT_(self.__class__.__name__, name)
96
+ name = _DOT_(self.typename, name)
98
97
  return _AttributeError(item=name, txt=_doesn_t_exist_)
99
98
 
100
99
  @property_RO
@@ -116,11 +115,16 @@ class ADict(dict):
116
115
  dict.update(self, items)
117
116
  return self # in RhumbLineBase.Intersecant2, _PseudoRhumbLine.Position
118
117
 
118
+ def _toL(self):
119
+ '''(INTERNAL) Get items as list.
120
+ '''
121
+ return list(_EQUAL_(*t) for t in self.items()) # _kwdstr
122
+
119
123
  def toRepr(self, **prec_fmt):
120
124
  '''Like C{repr(dict)} but with C{name} prefix and with
121
125
  C{floats} formatted by function L{pygeodesy.fstr}.
122
126
  '''
123
- n = _xattr(self, name=NN) or self.__class__.__name__
127
+ n = _xattr(self, name=NN) or self.typename
124
128
  return Fmt.PAREN(n, self._toT(_EQUAL_, **prec_fmt))
125
129
 
126
130
  def toStr(self, **prec_fmt):
@@ -135,6 +139,12 @@ class ADict(dict):
135
139
  kwds = _xkwds(kwds, prec=6, fmt=Fmt.F, sep=sep)
136
140
  return _COMMASPACE_.join(pairs(itemsorted(self), **kwds))
137
141
 
142
+ @property_RO
143
+ def typename(self):
144
+ '''Get this C{ADict}'s type name (C{str}).
145
+ '''
146
+ return type(self).__name__ # typename(type(self))
147
+
138
148
 
139
149
  class _Named(object):
140
150
  '''(INTERNAL) Root class for named objects.
@@ -294,7 +304,7 @@ class _Named(object):
294
304
 
295
305
  @arg which: The method (C{callable}).
296
306
  '''
297
- return _DOT_(self.classname, which.__name__ if callable(which) else _NN_)
307
+ return _DOT_(self.classname, typename(which) if callable(which) else _NN_)
298
308
 
299
309
  @property_doc_(''' the name (C{str}).''')
300
310
  def name(self):
@@ -314,7 +324,7 @@ class _Named(object):
314
324
  elif n != m:
315
325
  n = repr(n)
316
326
  c = self.classname
317
- t = _DOT_(c, Fmt.PAREN(self.rename.__name__, n))
327
+ t = _DOT_(c, Fmt.PAREN(typename(self.rename), n))
318
328
  n = _DOT_(c, Fmt.EQUALSPACED(name=n))
319
329
  m = Fmt.PAREN(_SPACE_('was', repr(m)))
320
330
  n = _SPACE_(n, m)
@@ -362,7 +372,7 @@ class _Named(object):
362
372
  def named4(self):
363
373
  '''Get the C{package.module.class} name I{and/or} the name or C{""} (C{str}).
364
374
  '''
365
- return _xjoined_(_DOT_(self.__module__, self.__class__.__name__), self.name)
375
+ return _xjoined_(_DOT_(self.__module__, self.typename), self.name)
366
376
 
367
377
  def _notImplemented(self, *args, **kwds):
368
378
  '''(INTERNAL) See function L{notImplemented}.
@@ -426,6 +436,12 @@ class _Named(object):
426
436
  # '''
427
437
  # return _DOT_(self, unstr(which, *args, **kwds))
428
438
 
439
+ @property_RO
440
+ def typename(self):
441
+ '''Get this object's type name (C{str}).
442
+ '''
443
+ return type(self).__name__ # typename(type(self))
444
+
429
445
  def _xnamed(self, inst, name=NN, **force):
430
446
  '''(INTERNAL) Set the instance' C{.name = self.name}.
431
447
 
@@ -586,7 +602,7 @@ class _NamedDict(ADict, _Named):
586
602
  def _KeyError(self, key, *value): # PYCHOK no cover
587
603
  '''(INTERNAL) Create a C{KeyError}.
588
604
  '''
589
- n = self.name or self.__class__.__name__
605
+ n = self.name or self.typename
590
606
  t = Fmt.SQUARE(n, key)
591
607
  if value:
592
608
  t = Fmt.EQUALSPACED(t, *value)
@@ -622,7 +638,7 @@ class _NamedEnum(_NamedDict):
622
638
  @arg Classes: Additional, acceptable classes or C{type}s.
623
639
  '''
624
640
  self._item_Classes = (Class,) + Classes
625
- n = _name__(**name) or NN(Class.__name__, _s_) # _DUNDER_nameof
641
+ n = _name__(**name) or NN(typename(Class), _s_)
626
642
  if n and _xvalid(n, underOK=True):
627
643
  _Named.name.fset(self, n) # see _Named.name
628
644
 
@@ -695,7 +711,7 @@ class _NamedEnum(_NamedDict):
695
711
  '''
696
712
  if all: # instantiate any remaining L{_LazyNamedEnumItem}
697
713
  _isa = isinstance
698
- for n, p in tuple(self.__class__.__dict__.items()):
714
+ for n, p in tuple(type(self).__dict__.items()):
699
715
  if _isa(p, _LazyNamedEnumItem):
700
716
  _ = getattr(self, n)
701
717
  return itemsorted(self) if asorted else ADict.items(self)
@@ -731,7 +747,7 @@ class _NamedEnum(_NamedDict):
731
747
  '''
732
748
  if item is all or item is any:
733
749
  _ = self.items(all=True)
734
- n = item.__name__
750
+ n = typename(item)
735
751
  else:
736
752
  try:
737
753
  n = item.name
@@ -1288,7 +1304,7 @@ class _NamedTuple(tuple, _Named):
1288
1304
  t = Fmt.SQUARE(_Units_=i) # PYCHOK no cover
1289
1305
  raise _TypeError(self._DOT_(t), u)
1290
1306
 
1291
- self.__class__._validated = True
1307
+ type(self)._validated = True
1292
1308
 
1293
1309
  def _xtend(self, xTuple, *items, **name):
1294
1310
  '''(INTERNAL) Extend this C{Named-Tuple} with C{items} to an other B{C{xTuple}}.
@@ -1297,7 +1313,7 @@ class _NamedTuple(tuple, _Named):
1297
1313
  if len(xTuple._Names_) != (len(self._Names_) + len(items)) or \
1298
1314
  xTuple._Names_[:len(self)] != self._Names_: # PYCHOK no cover
1299
1315
  c = NN(self.classname, repr(self._Names_))
1300
- x = NN(xTuple.__name__, repr(xTuple._Names_))
1316
+ x = NN(typename(xTuple), repr(xTuple._Names_))
1301
1317
  raise TypeError(_SPACE_(c, _vs_, x))
1302
1318
  t = self + items
1303
1319
  return xTuple(t, name=self._name__(name)) # .reUnit(*self._Units_)
@@ -1357,7 +1373,7 @@ def classname(inst, prefixed=None):
1357
1373
  @return: The B{C{inst}}'s C{[module.]class} name (C{str}).
1358
1374
  '''
1359
1375
  if prefixed is None:
1360
- prefixed = getattr(inst, classnaming.__name__, prefixed)
1376
+ prefixed = getattr(inst, typename(classnaming), prefixed)
1361
1377
  return modulename(inst.__class__, prefixed=prefixed)
1362
1378
 
1363
1379
 
@@ -1369,7 +1385,7 @@ def classnaming(prefixed=None):
1369
1385
  @return: Previous class naming setting (C{bool}).
1370
1386
  '''
1371
1387
  t = _Named._classnaming
1372
- if prefixed in (True, False):
1388
+ if isbool(prefixed):
1373
1389
  _Named._classnaming = prefixed
1374
1390
  return t
1375
1391
 
@@ -1385,9 +1401,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1385
1401
  @return: The B{C{class}}'s C{[module.]class} name (C{str}).
1386
1402
  '''
1387
1403
  try:
1388
- n = clas.__name__
1404
+ n = typename(clas)
1389
1405
  except AttributeError:
1390
- n = clas if isstr(clas) else _DUNDER_name_
1406
+ n = clas if isstr(clas) else _DNAME_
1391
1407
  if prefixed or (classnaming() if prefixed is None else False):
1392
1408
  try:
1393
1409
  m = clas.__module__.rsplit(_DOT_, 1)
@@ -1406,7 +1422,7 @@ def modulename(clas, prefixed=None): # in .basics._xversion
1406
1422
  # if name: # is given
1407
1423
  # n = _name__(**name) if isinstance(name, dict) else str(name)
1408
1424
  # elif name__ is not None:
1409
- # n = getattr(name__, _DUNDER_name_, NN) # _xattr(name__, __name__=NN)
1425
+ # n = getattr(name__, _DNAME_, NN) # _xattr(name__, __name__=NN)
1410
1426
  # else:
1411
1427
  # n = name # NN or None or {} or any False type
1412
1428
  # if _or_nameof is not None and not n:
@@ -1443,7 +1459,7 @@ def _name2__(name=NN, name__=None, _or_nameof=None, **kwds):
1443
1459
  else:
1444
1460
  n = str(name)
1445
1461
  elif name__ is not None:
1446
- n = _DUNDER_nameof(name__, NN)
1462
+ n = typename(name__, NN)
1447
1463
  else:
1448
1464
  n = name if name is None else NN
1449
1465
  if _or_nameof is not None and not n:
@@ -1461,7 +1477,7 @@ def nameof(inst):
1461
1477
  n = _xattr(inst, name=NN)
1462
1478
  if not n: # and isinstance(inst, property):
1463
1479
  try:
1464
- n = inst.fget.__name__
1480
+ n = typename(inst.fget)
1465
1481
  except AttributeError:
1466
1482
  n = NN
1467
1483
  return n
@@ -1470,7 +1486,7 @@ def nameof(inst):
1470
1486
  def _notDecap(where):
1471
1487
  '''De-Capitalize C{where.__name__}.
1472
1488
  '''
1473
- n = where.__name__
1489
+ n = typename(where)
1474
1490
  c = n[3].lower() # len(_not_)
1475
1491
  return NN(n[:3], _SPACE_, c, n[4:])
1476
1492
 
@@ -1478,8 +1494,8 @@ def _notDecap(where):
1478
1494
  def _notError(inst, name, args, kwds): # PYCHOK no cover
1479
1495
  '''(INTERNAL) Format an error message.
1480
1496
  '''
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])
1497
+ n = _DOT_(classname(inst, prefixed=True), typename(name, name))
1498
+ m = _COMMASPACE_.join(modulename(c, prefixed=True) for c in type(inst).__mro__[1:-1])
1483
1499
  return _COMMASPACE_(unstr(n, *args, **kwds), Fmt.PAREN(_MRO_, m))
1484
1500
 
1485
1501
 
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:
pygeodesy/props.py CHANGED
@@ -13,20 +13,20 @@ choices, see callable L{DeprecationWarnings} below.
13
13
  from pygeodesy.basics import isclass as _isclass
14
14
  from pygeodesy.errors import _AssertionError, _AttributeError, \
15
15
  _xcallable, _xkwds_get
16
- # from pygeodesy.internals import _tailof # from .lazily
16
+ from pygeodesy.internals import _tailof, typename
17
17
  from pygeodesy.interns import MISSING, NN, _an_, _COMMASPACE_, \
18
18
  _DEPRECATED_, _DOT_, _EQUALSPACED_, \
19
19
  _immutable_, _invalid_, _module_, \
20
20
  _N_A_, _NL_, _not_, _SPACE_, _UNDER_
21
21
  # from pygeodesy.named import callname # _MODS, avoid circular
22
22
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
23
- _FOR_DOCS, _WARNINGS_X_DEV, _tailof
23
+ _FOR_DOCS, _WARNINGS_X_DEV
24
24
  # from pygeodesy.streprs import Fmt # _MODS
25
25
 
26
26
  from functools import wraps as _wraps
27
27
 
28
28
  __all__ = _ALL_LAZY.props
29
- __version__ = '24.11.06'
29
+ __version__ = '25.04.14'
30
30
 
31
31
  _class_ = 'class'
32
32
  _DNL_ = _NL_ * 2 # PYCHOK used!
@@ -45,7 +45,7 @@ def _allPropertiesOf(Clas_or_inst, *Bases, **excls):
45
45
  S = Clas_or_inst, # just this Clas
46
46
  else: # class and super-classes of inst
47
47
  try:
48
- S = Clas_or_inst.__class__.__mro__[:-1] # not object
48
+ S = type(Clas_or_inst).__mro__[:-1] # not object
49
49
  except AttributeError:
50
50
  raise
51
51
  S = () # not an inst
@@ -162,7 +162,7 @@ class _PropertyBase(property):
162
162
  _xcallable(getter=method, fget=fget)
163
163
 
164
164
  self.method = method
165
- self.name = method.__name__
165
+ self.name = typename(method)
166
166
  d = doc or method.__doc__
167
167
  if _FOR_DOCS and d:
168
168
  self.__doc__ = d # PYCHOK no cover
@@ -173,8 +173,8 @@ class _PropertyBase(property):
173
173
  '''(INTERNAL) Return an C{AttributeError} instance.
174
174
  '''
175
175
  if farg:
176
- n = _DOT_(self.name, nameter.__name__)
177
- n = _SPACE_(n, farg.__name__)
176
+ n = _DOT_(self.name, typename(nameter))
177
+ n = _SPACE_(n, typename(farg))
178
178
  else:
179
179
  n = nameter
180
180
  e = _SPACE_(kind, _MODS.named.classname(self))
@@ -349,7 +349,7 @@ class property_RO(_PropertyBase):
349
349
  else:
350
350
  d = getattr(inst.__class__, uname, MISSING)
351
351
  # if d is MISSING: # XXX superfluous
352
- # for c in inst.__class__.__mro__[:-1]:
352
+ # for c in type(inst).__mro__[:-1]:
353
353
  # if uname in c.__dict__:
354
354
  # d = c.__dict__[uname]
355
355
  # break
@@ -409,7 +409,7 @@ class property_ROver(_property_RO___):
409
409
  setattr(c, n, v) # overwrite property_ROver
410
410
  break
411
411
  else:
412
- n = _DOT_(C.__name__, n)
412
+ n = _DOT_(typename(C), n)
413
413
  raise _AssertionError(_EQUALSPACED_(n, v))
414
414
  return v
415
415
 
@@ -421,7 +421,7 @@ class _NamedProperty(property): # in .named
421
421
  def name(self):
422
422
  '''Get the name of this C{property} (C{str}).
423
423
  '''
424
- return self.fget.__name__
424
+ return typename(self.fget)
425
425
 
426
426
 
427
427
  def property_doc_(doc):
@@ -460,16 +460,16 @@ def _deprecated(call, kind, qual_d):
460
460
  @see: Brett Slatkin, "Effective Python", 2019 page 105, 2nd
461
461
  ed, Addison-Wesley.
462
462
  '''
463
- doc = _docof(call)
463
+ doc = _DOCof(call)
464
464
 
465
465
  @_wraps(call) # PYCHOK self?
466
466
  def _deprecated_call(*args, **kwds):
467
467
  if qual_d: # function
468
- q = qual_d
468
+ q = qual_d
469
469
  elif args: # method
470
- q = _qualified(args[0], call.__name__)
470
+ q = _qualified(args[0], typename(call))
471
471
  else: # PYCHOK no cover
472
- q = call.__name__
472
+ q = typename(call)
473
473
  _throwarning(kind, q, doc)
474
474
  return call(*args, **kwds)
475
475
 
@@ -484,8 +484,8 @@ def deprecated_class(cls_or_class):
484
484
  @note: NOT a decorator!
485
485
  '''
486
486
  if _WARNINGS_X_DEV:
487
- q = _DOT_(cls_or_class.__module__, cls_or_class.__name__)
488
- _throwarning(_class_, q, cls_or_class.__doc__)
487
+ q = _DOT_(cls_or_class.__module__, typename(cls_or_class))
488
+ _throwarning(_class_, q, cls_or_class.__doc__) # _DDOC_
489
489
 
490
490
 
491
491
  def deprecated_function(call):
@@ -496,7 +496,7 @@ def deprecated_function(call):
496
496
  @return: The B{C{call}} DEPRECATED.
497
497
  '''
498
498
  return _deprecated(call, _function_, _DOT_(
499
- call.__module__, call.__name__)) if \
499
+ call.__module__, typename(call))) if \
500
500
  _WARNINGS_X_DEV else call
501
501
 
502
502
 
@@ -524,13 +524,13 @@ if _WARNINGS_X_DEV:
524
524
  def __init__(self, method):
525
525
  '''Decorator for a DEPRECATED C{property} or C{Property} getter.
526
526
  '''
527
- doc = _docof(method)
527
+ doc = _DOCof(method)
528
528
 
529
529
  def _fget(inst): # PYCHOK no cover
530
530
  '''Get the C{property} or C{Property} value.
531
531
  '''
532
532
  q = _qualified(inst, self.name)
533
- _throwarning(property.__name__, q, doc)
533
+ _throwarning(typename(property), q, doc)
534
534
  return self.method(inst) # == method
535
535
 
536
536
  _PropertyBase.__init__(self, method, _fget, None, doc=doc)
@@ -554,7 +554,7 @@ if _WARNINGS_X_DEV:
554
554
  '''Set the C{property} or C{Property} value.
555
555
  '''
556
556
  q = _qualified(inst, self.name)
557
- _throwarning(property.__name__, q, _docof(method))
557
+ _throwarning(typename(property), q, _DOCof(method))
558
558
  method(inst, val)
559
559
  # self._update(inst) # un-cache this item
560
560
 
@@ -594,7 +594,7 @@ def deprecated_property_RO(method):
594
594
  def _deprecated_RO(method, _RO):
595
595
  '''(INTERNAL) Create a DEPRECATED C{property_RO} or C{Property_RO}.
596
596
  '''
597
- doc = _docof(method)
597
+ doc = _DOCof(method)
598
598
 
599
599
  if _WARNINGS_X_DEV:
600
600
 
@@ -606,7 +606,7 @@ def _deprecated_RO(method, _RO):
606
606
 
607
607
  def _fget(self, inst): # PYCHOK no cover
608
608
  q = _qualified(inst, self.name)
609
- _throwarning(_RO.__name__, q, doc)
609
+ _throwarning(typename(_RO), q, doc)
610
610
  return self.method(inst)
611
611
 
612
612
  return _Deprecated_RO(method)
@@ -614,7 +614,7 @@ def _deprecated_RO(method, _RO):
614
614
  return _RO(method, doc=doc)
615
615
 
616
616
 
617
- def _docof(obj):
617
+ def _DOCof(obj):
618
618
  '''(INTERNAL) Get uniform DEPRECATED __doc__ string.
619
619
  '''
620
620
  try:
@@ -629,8 +629,8 @@ def _qualified(inst, name):
629
629
  '''(INTERNAL) Fully qualify a name.
630
630
  '''
631
631
  # _DOT_(inst.classname, name), not _DOT_(inst.named4, name)
632
- c = inst.__class__
633
- q = _DOT_(c.__module__, c.__name__, name)
632
+ t = type(inst)
633
+ q = _DOT_(t.__module__, typename(t), name) # _DMODULE_
634
634
  return q
635
635
 
636
636