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/azimuthal.py CHANGED
@@ -42,19 +42,20 @@ altitude in Earth radii<https://WikiPedia.org/wiki/Azimuthal_equidistant_project
42
42
  # make sure int/int division yields float quotient, see .basics
43
43
  from __future__ import division as _; del _ # PYCHOK semicolon
44
44
 
45
- # from pygeodesy.basics import _xinstanceof # from .ellipsoidalBase
45
+ # from pygeodesy.basics import _isin, _xinstanceof # from .ellipsoidalBase
46
46
  from pygeodesy.constants import EPS, EPS0, EPS1, NAN, isnon0, _umod_360, \
47
47
  _EPStol, _0_0, _0_1, _0_5, _1_0, _N_1_0, _2_0
48
48
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB, \
49
- _xinstanceof
49
+ _isin, _xinstanceof
50
50
  from pygeodesy.datums import _spherical_datum, _WGS84
51
51
  from pygeodesy.errors import _ValueError, _xdatum, _xkwds
52
52
  from pygeodesy.fmath import euclid, fdot_, hypot as _hypot, Fsum
53
53
  # from pygeodesy.fsums import Fsum # from .fmath
54
54
  # from pygeodesy.formy import antipode # _MODS
55
+ # from pygeodesy.internals import typename # from .karney
55
56
  from pygeodesy.interns import _azimuth_, _datum_, _lat_, _lon_, _scale_, \
56
57
  _SPACE_, _x_, _y_
57
- from pygeodesy.karney import _norm180
58
+ from pygeodesy.karney import _norm180, typename
58
59
  from pygeodesy.latlonBase import _MODS, LatLonBase as _LLB
59
60
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _FOR_DOCS # ALL_MODS
60
61
  from pygeodesy.named import _name__, _name2__, _NamedBase, _NamedTuple, _Pass
@@ -70,7 +71,7 @@ from pygeodesy.utily import asin1, atan1, atan2, atan2b, atan2d, \
70
71
  from math import acos, degrees, fabs, sin, sqrt
71
72
 
72
73
  __all__ = _ALL_LAZY.azimuthal
73
- __version__ = '24.11.24'
74
+ __version__ = '25.04.14'
74
75
 
75
76
  _EPS_K = _EPStol * _0_1 # Karney's eps_ or _EPSmin * _0_1?
76
77
  _over_horizon_ = 'over horizon'
@@ -112,7 +113,7 @@ class _AzimuthalBase(_NamedBase):
112
113
 
113
114
  @raise TypeError: Invalid B{C{datum}}.
114
115
  '''
115
- if datum not in (None, self._datum):
116
+ if not _isin(datum, None, self._datum):
116
117
  self._datum = _spherical_datum(datum, **name)
117
118
  if name:
118
119
  self.name = name
@@ -1088,7 +1089,7 @@ class Stereographic(_AzimuthalBase):
1088
1089
  def k0(self, factor):
1089
1090
  '''Set the central scale factor (C{scalar}).
1090
1091
  '''
1091
- n = Stereographic.k0.fget.__name__ # 'k0', name__=Stereographic.k0.fget
1092
+ n = typename(Stereographic.k0.fget) # 'k0', name__=Stereographic.k0.fget
1092
1093
  self._k0 = Scalar_(factor, name=n, low=EPS, high=2) # XXX high=1, 2, other?
1093
1094
  self._k02 = self._k0 * _2_0
1094
1095
 
pygeodesy/basics.py CHANGED
@@ -20,8 +20,8 @@ from pygeodesy.errors import _AttributeError, _ImportError, _NotImplementedError
20
20
  _TypeError, _TypesError, _ValueError, _xAssertionError, \
21
21
  _xkwds_get1
22
22
  # from pygeodesy.fsums import _isFsum_2Tuple # _MODS
23
- from pygeodesy.internals import _0_0, _enquote, _getenv, _passarg, _PYGEODESY, \
24
- _version_info
23
+ from pygeodesy.internals import _0_0, _enquote, _envPYGEODESY, _getenv, _passarg, \
24
+ _PYGEODESY_ENV, typename, _version_info
25
25
  from pygeodesy.interns import MISSING, NN, _1_, _by_, _COMMA_, _DOT_, _DEPRECATED_, \
26
26
  _ELLIPSIS4_, _EQUAL_, _in_, _invalid_, _N_A_, _not_, \
27
27
  _not_scalar_, _odd_, _SPACE_, _UNDER_, _version_
@@ -37,7 +37,7 @@ from math import copysign as _copysign
37
37
  # import inspect as _inspect # _MODS
38
38
 
39
39
  __all__ = _ALL_LAZY.basics
40
- __version__ = '25.01.17'
40
+ __version__ = '25.04.14'
41
41
 
42
42
  _below_ = 'below'
43
43
  _list_tuple_types = (list, tuple)
@@ -312,17 +312,23 @@ def iscomplex(obj, both=False):
312
312
  return False
313
313
 
314
314
 
315
- def isDEPRECATED(obj):
316
- '''Is B{C{obj}}ect a C{DEPRECATED} class, method or function?
315
+ def isDEPRECATED(obj, outer=1):
316
+ '''Is B{C{obj}}ect or its outer C{type} a C{DEPRECATED}
317
+ class, constant, method or function?
317
318
 
318
319
  @return: C{True} if C{DEPRECATED}, {False} if not or
319
320
  C{None} if undetermined.
320
321
  '''
321
- try: # XXX inspect.getdoc(obj) or obj.__doc__
322
- doc = obj.__doc__.lstrip()
323
- return bool(doc and doc.startswith(_DEPRECATED_))
324
- except AttributeError:
325
- return None
322
+ r = None
323
+ for _ in range(max(0, outer) + 1):
324
+ try: # inspect.getdoc(obj)
325
+ if _DEPRECATED_ in obj.__doc__:
326
+ return True
327
+ r = False
328
+ except AttributeError:
329
+ pass
330
+ obj = type(obj)
331
+ return r
326
332
 
327
333
 
328
334
  def isfloat(obj, both=False):
@@ -352,6 +358,13 @@ except AttributeError: # Python 2-
352
358
  and not obj[:1].isdigit())
353
359
 
354
360
 
361
+ def _isin(obj, *objs):
362
+ '''(INTERNAL) Return C{bool(obj in objs)} with C{True} and C{False} matching.
363
+ '''
364
+ return any(o is obj for o in objs) or \
365
+ any(o == obj for o in objs if not isbool(o))
366
+
367
+
355
368
  def isinstanceof(obj, *Classes):
356
369
  '''Is B{C{obj}}ect an instance of one of the C{Classes}?
357
370
 
@@ -603,7 +616,7 @@ def map1(fun1, *xs): # XXX map_
603
616
 
604
617
  @return: Function results (C{tuple}).
605
618
  '''
606
- return tuple(map(fun1, xs))
619
+ return tuple(map(fun1, xs)) # if len(xs) != 1 else fun1(xs[0])
607
620
 
608
621
 
609
622
  def map2(fun, *xs, **strict):
@@ -905,8 +918,8 @@ def _xiterablen(obj):
905
918
  def _xiterror(obj, _xwhich):
906
919
  '''(INTERNAL) Helper for C{_xinterable} and C{_xiterablen}.
907
920
  '''
908
- t = _not_(_xwhich.__name__[2:]) # _DUNDER_nameof
909
- raise _TypeError(repr(obj), txt=t)
921
+ t = typename(_xwhich)[2:] # less '_x'
922
+ raise _TypeError(repr(obj), txt=_not_(t))
910
923
 
911
924
 
912
925
  def _xnumpy(where, *required):
@@ -928,13 +941,13 @@ def _xor(x, *xs):
928
941
  return x
929
942
 
930
943
 
931
- def _xpackages(_xpkgf):
944
+ def _xpackages(_xhich):
932
945
  '''(INTERNAL) Check dependency to be excluded.
933
946
  '''
934
947
  if _XPACKAGES: # PYCHOK no cover
935
- n = _xpkgf.__name__[2:] # _DUNDER_nameof, less '_x'
948
+ n = typename(_xhich)[2:] # less '_x'
936
949
  if n.lower() in _XPACKAGES:
937
- E = _PYGEODESY(_xpackages)
950
+ E = _PYGEODESY_ENV(_xpackages_)
938
951
  x = _SPACE_(n, _in_, E)
939
952
  e = _enquote(_getenv(E, NN))
940
953
  raise ImportError(_EQUAL_(x, e))
@@ -984,7 +997,7 @@ def _xversion(package, where, *required, **name):
984
997
  if required:
985
998
  t = _version_info(package)
986
999
  if t[:len(required)] < required:
987
- t = _SPACE_(package.__name__, # _DUNDER_nameof
1000
+ t = _SPACE_(typename(package),
988
1001
  _version_, _DOT_(*t),
989
1002
  _below_, _DOT_(*required),
990
1003
  _req_d_by(where, **name))
@@ -1011,7 +1024,8 @@ else: # Python 3.10+
1011
1024
  def _zip(*args):
1012
1025
  return zip(*args, strict=True)
1013
1026
 
1014
- _XPACKAGES = _splituple(_getenv(_PYGEODESY(_xpackages), NN).lower()) # test/bases._X_OK
1027
+ _xpackages_ = typename(_xpackages).lstrip(_UNDER_)
1028
+ _XPACKAGES = _splituple(_envPYGEODESY(_xpackages_).lower()) # test/bases._X_OK
1015
1029
 
1016
1030
  # **) MIT License
1017
1031
  #
pygeodesy/booleans.py CHANGED
@@ -17,12 +17,14 @@ C{reverse-difference}, C{sum} and C{union}.
17
17
  # make sure int/int division yields float quotient, see .basics
18
18
  from __future__ import division as _; del _ # PYCHOK semicolon
19
19
 
20
- from pygeodesy.basics import isodd, issubclassof, map2, _xscalar
20
+ from pygeodesy.basics import _isin, isodd, issubclassof, map2, \
21
+ _xscalar, typename
21
22
  from pygeodesy.constants import EPS, EPS2, INT0, _0_0, _0_5, _1_0
22
23
  from pygeodesy.errors import ClipError, _IsnotError, _TypeError, \
23
24
  _ValueError, _xattr, _xkwds_get, _xkwds_pop2
24
- from pygeodesy.fmath import favg, fdot_, hypot, hypot2
25
+ from pygeodesy.fmath import favg, Fdot_, fdot_, hypot, hypot2
25
26
  # from pygeodesy.fsums import fsum1 # _MODS
27
+ # from pygeodesy.internals import typename # from .basics
26
28
  from pygeodesy.interns import NN, _BANG_, _clipid_, _COMMASPACE_, \
27
29
  _composite_, _DOT_, _duplicate_, _e_, \
28
30
  _ELLIPSIS_, _few_, _height_, _lat_, _LatLon_, \
@@ -43,7 +45,7 @@ from pygeodesy.utily import fabs, _unrollon, _Wrap
43
45
  # from math import fabs # from .utily
44
46
 
45
47
  __all__ = _ALL_LAZY.booleans
46
- __version__ = '24.11.07'
48
+ __version__ = '25.04.30'
47
49
 
48
50
  _0EPS = EPS # near-zero, positive
49
51
  _EPS0 = -EPS # near-zero, negative
@@ -352,11 +354,11 @@ class LatLonFHP(_LatLonBool):
352
354
  def _isduplicate(self):
353
355
  # Is this point a I{duplicate} intersection?
354
356
  p = self._dupof
355
- return bool(p and self._linked
356
- and p is not self
357
- and p == self
358
- # and p._alpha in (None, self._alpha)
359
- and self._alpha in (_0_0, p._alpha))
357
+ return bool(p and self._linked
358
+ and p is not self
359
+ and p == self
360
+ # and _isin(p._alpha, None, self._alpha)
361
+ and _isin(self._alpha, _0_0, p._alpha))
360
362
 
361
363
  # @property_RO
362
364
  # def _isduplicated(self):
@@ -940,7 +942,7 @@ class _CompositeBase(_Named):
940
942
  c = Fmt.SQUARE(c) if c > 1 else NN
941
943
  n = Fmt.SQUARE(len(self))
942
944
  t = Fmt.PAREN(self) # XXX not unstr
943
- return NN(self.__class__.__name__, c, n, t)
945
+ return NN(self.typename, c, n, t)
944
946
 
945
947
  def __str__(self):
946
948
  '''String C{str} of this composite.
@@ -1051,7 +1053,7 @@ class _CompositeBase(_Named):
1051
1053
  def _kwds(self, op, **more):
1052
1054
  # Get all keyword arguments as C{dict}.
1053
1055
  kwds = dict(raiser=self.raiser, eps=self.eps,
1054
- name=self.name or op.__name__)
1056
+ name=self.name or typename(op))
1055
1057
  kwds.update(more)
1056
1058
  return kwds
1057
1059
 
@@ -1105,7 +1107,7 @@ class _CompositeBase(_Named):
1105
1107
  def _sum(self, other, op):
1106
1108
  # Combine this and an C{other} composite
1107
1109
  LL = self._LL
1108
- sp = self.copy(name=self.name or op.__name__)
1110
+ sp = self.copy(name=self.name or typename(op))
1109
1111
  sp._clips, sid = (), INT0 # new clips
1110
1112
  for cp in (self, other):
1111
1113
  for c in cp._clips:
@@ -1610,8 +1612,8 @@ class _EdgeGH(object):
1610
1612
 
1611
1613
  def _alpha2(self, x, y, dx, dy):
1612
1614
  # Return C{(alpha)}, see .points.nearestOn5
1613
- a = fdot_(y, dy, x, dx) / self._hypot2
1614
- d = fdot_(y, dx, -x, dy) / self._hypot0
1615
+ a = Fdot_(y, dy, x, dx).fover(self._hypot2)
1616
+ d = Fdot_(y, dx, -x, dy).fover(self._hypot0)
1615
1617
  return a, fabs(d)
1616
1618
 
1617
1619
  def _Error(self, n, *args, **kwds): # PYCHOK no cover
@@ -1653,10 +1655,10 @@ class _EdgeGH(object):
1653
1655
  if fabs(d) > _0EPS: # non-parallel edges
1654
1656
  dx = x - c1_x
1655
1657
  dy = y - c1_y
1656
- ca = fdot_(sx, dy, -sy, dx) / d
1658
+ ca = Fdot_(sx, dy, -sy, dx).fover(d)
1657
1659
  if _0EPS < ca < _EPS1 or (self._xtend and
1658
1660
  _EPS0 < ca < _1EPS):
1659
- sa = fdot_(cx, dy, -cy, dx) / d
1661
+ sa = Fdot_(cx, dy, -cy, dx).fover(d)
1660
1662
  if _0EPS < sa < _EPS1 or (self._xtend and
1661
1663
  _EPS0 < sa < _1EPS):
1662
1664
  yield (y + sa * sy), (x + sa * sx), sa, ca
@@ -1667,7 +1669,7 @@ class _EdgeGH(object):
1667
1669
 
1668
1670
  elif self._raiser and not (ca < _EPS0 or ca > _1EPS): # PYCHOK no cover
1669
1671
  # intersection at c1 or c2 or at c1 or c2 and s1 or s2
1670
- sa = fdot_(cx, dy, -cy, dx) / d
1672
+ sa = Fdot_(cx, dy, -cy, dx).fover(d)
1671
1673
  e = 2 if sa < _EPS0 or sa > _1EPS else 3
1672
1674
  raise self._Error(e, c1, c2, ca=ca)
1673
1675
 
@@ -10,28 +10,29 @@ U{https://www.Movable-Type.co.UK/scripts/latlong-vectors.html} and
10
10
  U{https://www.Movable-Type.co.UK/scripts/geodesy/docs/latlon-ellipsoidal.js.html}.
11
11
  '''
12
12
 
13
- # from pygeodesy.basics import _xinstanceof # from .datums
13
+ from pygeodesy.basics import _isin, _xinstanceof, typename
14
14
  from pygeodesy.constants import EPS, EPS0, INT0, PI2, _isfinite, isnear0, \
15
15
  _0_0, _1_0, _N_1_0, _2_0, _4_0, _6_0
16
16
  from pygeodesy.datums import Datum, _earth_ellipsoid, _spherical_datum, \
17
- Transform, _WGS84, _xinstanceof
17
+ Transform, _WGS84
18
18
  # from pygeodesy.ecef import EcefKarney # _MODS
19
+ from pygeodesy.ecefLocals import _EcefLocal
19
20
  from pygeodesy.errors import _IsnotError, _TypeError, _ValueError, _xattr, \
20
21
  _xdatum, _xkwds, _xkwds_get, _xkwds_pop2
21
22
  from pygeodesy.fmath import cbrt, hypot, hypot_, hypot2, fabs, sqrt # hypot
22
23
  # from pygeodesy.formy import _hartzell # _MODS
23
24
  from pygeodesy.fsums import fsumf_, Fmt
25
+ # from pygeodesy.internals import typename # from .basics
24
26
  from pygeodesy.interns import _COMMASPACE_, _datum_, _no_, _phi_
25
27
  from pygeodesy.interns import _ellipsoidal_, _spherical_ # PYCHOK used!
26
28
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
27
- from pygeodesy.named import _name2__, _NamedLocal, _Pass
29
+ from pygeodesy.named import _name2__, _Pass
28
30
  from pygeodesy.namedTuples import LatLon4Tuple, _NamedTupleTo , Vector3Tuple, \
29
31
  Vector4Tuple, Bearing2Tuple # PYCHOK .sphericalBase
30
32
  # from pygeodesy.nvectorBase import _N_vector # _MODS
31
33
  from pygeodesy.props import deprecated_method, Property, Property_RO, property_doc_, \
32
34
  property_RO, _update_all
33
- # from pygeodesy,resections import cassini, collins5, pierlot, pierlotx, \
34
- # tienstra7 # _MODS
35
+ # from pygeodesy import resections as _resections # _MODS.into
35
36
  # from pygeodesy.streprs import Fmt # from .fsums
36
37
  # from pygeodesy.triaxials import Triaxial_ # _MODS
37
38
  from pygeodesy.units import Degrees, Height, _heigHt, _isMeter, Meter, Radians
@@ -43,13 +44,14 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
43
44
  # from math import degrees, fabs, radians, sqrt # from .fmath, .utily
44
45
 
45
46
  __all__ = _ALL_LAZY.cartesianBase
46
- __version__ = '24.12.04'
47
+ __version__ = '25.04.28'
47
48
 
48
- _r_ = 'r'
49
- _theta_ = 'theta'
49
+ _r_ = 'r'
50
+ _resections = _MODS.into(resections=__name__)
51
+ _theta_ = 'theta'
50
52
 
51
53
 
52
- class CartesianBase(Vector3d, _NamedLocal):
54
+ class CartesianBase(Vector3d, _EcefLocal):
53
55
  '''(INTERNAL) Base class for ellipsoidal and spherical C{Cartesian}.
54
56
  '''
55
57
  _datum = None # L{Datum}, to be overriden
@@ -112,8 +114,8 @@ class CartesianBase(Vector3d, _NamedLocal):
112
114
 
113
115
  @see: Function L{pygeodesy.cassini} for references and more details.
114
116
  '''
115
- return _MODS.resections.cassini(self, pointB, pointC, alpha, beta,
116
- useZ=useZ, datum=self.datum)
117
+ return _resections.cassini(self, pointB, pointC, alpha, beta,
118
+ useZ=useZ, datum=self.datum)
117
119
 
118
120
  @deprecated_method
119
121
  def collins(self, pointB, pointC, alpha, beta, useZ=False):
@@ -148,8 +150,8 @@ class CartesianBase(Vector3d, _NamedLocal):
148
150
 
149
151
  @see: Function L{pygeodesy.collins5} for references and more details.
150
152
  '''
151
- return _MODS.resections.collins5(self, pointB, pointC, alpha, beta,
152
- useZ=useZ, datum=self.datum)
153
+ return _resections.collins5(self, pointB, pointC, alpha, beta,
154
+ useZ=useZ, datum=self.datum)
153
155
 
154
156
  @deprecated_method
155
157
  def convertDatum(self, datum2, **datum):
@@ -199,7 +201,7 @@ class CartesianBase(Vector3d, _NamedLocal):
199
201
  '''
200
202
  n, kwds = _name2__(name_Cartesian_kwds, _or_nameof=self)
201
203
  if Cartesian is None:
202
- r = self._Ltp._local2ecef(delta, nine=True)
204
+ r = self._ltp._local2ecef(delta, nine=True) # _EcefLocal._ltp
203
205
  else:
204
206
  d = self.datum
205
207
  if not d:
@@ -207,7 +209,7 @@ class CartesianBase(Vector3d, _NamedLocal):
207
209
  t = _xkwds_get(kwds, datum=d)
208
210
  if _xattr(t, ellipsoid=None) != d.ellipsoid:
209
211
  raise _TypeError(datum=t, txt=str(d))
210
- c = self._Ltp._local2ecef(delta, nine=False)
212
+ c = self._ltp._local2ecef(delta, nine=False) # _EcefLocal._ltp
211
213
  r = Cartesian(*c, **kwds)
212
214
  return r.renamed(n) if n else r
213
215
 
@@ -304,7 +306,7 @@ class CartesianBase(Vector3d, _NamedLocal):
304
306
 
305
307
  @raise TypeError: Invalid or undefined B{C{earth}} or C{datum}.
306
308
  '''
307
- n = self.height3.__name__
309
+ n = typename(self.height3)
308
310
  d = self.datum if earth is None else _spherical_datum(earth, name=n)
309
311
  c, h = self, _heigHt(self, height)
310
312
  if h and d:
@@ -357,7 +359,7 @@ class CartesianBase(Vector3d, _NamedLocal):
357
359
 
358
360
  @see: Methods L{Ellipsoid.height4} and L{Triaxial_.height4} for more information.
359
361
  '''
360
- n = self.height4.__name__
362
+ n = typename(self.height4)
361
363
  d = self.datum if earth is None else earth
362
364
  if normal and d is self.datum:
363
365
  r = self._height4
@@ -504,8 +506,8 @@ class CartesianBase(Vector3d, _NamedLocal):
504
506
 
505
507
  @see: Function L{pygeodesy.pierlot} for references and more details.
506
508
  '''
507
- return _MODS.resections.pierlot(self, point2, point3, alpha12, alpha23,
508
- useZ=useZ, eps=eps, datum=self.datum)
509
+ return _resections.pierlot(self, point2, point3, alpha12, alpha23,
510
+ useZ=useZ, eps=eps, datum=self.datum)
509
511
 
510
512
  def pierlotx(self, point2, point3, alpha1, alpha2, alpha3, useZ=False):
511
513
  '''3-Point resection between this and two other points using U{Pierlot
@@ -531,8 +533,8 @@ class CartesianBase(Vector3d, _NamedLocal):
531
533
 
532
534
  @see: Function L{pygeodesy.pierlotx} for references and more details.
533
535
  '''
534
- return _MODS.resections.pierlotx(self, point2, point3, alpha1, alpha2, alpha3,
535
- useZ=useZ, datum=self.datum)
536
+ return _resections.pierlotx(self, point2, point3, alpha1, alpha2, alpha3,
537
+ useZ=useZ, datum=self.datum)
536
538
 
537
539
  def Roc2(self, earth=None):
538
540
  '''Compute this cartesian's I{normal} and I{pseudo, z-based} radius of curvature.
@@ -605,8 +607,8 @@ class CartesianBase(Vector3d, _NamedLocal):
605
607
 
606
608
  @see: Function L{pygeodesy.tienstra7} for references and more details.
607
609
  '''
608
- return _MODS.resections.tienstra7(self, pointB, pointC, alpha, beta, gamma,
609
- useZ=useZ, datum=self.datum)
610
+ return _resections.tienstra7(self, pointB, pointC, alpha, beta, gamma,
611
+ useZ=useZ, datum=self.datum)
610
612
 
611
613
  @deprecated_method
612
614
  def to2ab(self): # PYCHOK no cover
@@ -659,7 +661,7 @@ class CartesianBase(Vector3d, _NamedLocal):
659
661
  '''
660
662
  _xinstanceof(Datum, datum2=datum2)
661
663
 
662
- c = self if datum in (None, self.datum) else \
664
+ c = self if _isin(datum, None, self.datum) else \
663
665
  self.toDatum(datum)
664
666
 
665
667
  i, d = False, c.datum
pygeodesy/clipy.py CHANGED
@@ -12,11 +12,12 @@ I{Greiner-Hormann} and L{clipSH} and L{clipSH3} I{Sutherland-Hodgeman}.
12
12
  # make sure int/int division yields float quotient, see .basics
13
13
  from __future__ import division as _; del _ # PYCHOK semicolon
14
14
 
15
- # from pygeodesy.basics import len2 # from .fmath
15
+ from pygeodesy.basics import len2, typename
16
16
  from pygeodesy.constants import EPS, _0_0, _1_0
17
17
  from pygeodesy.errors import _AssertionError, ClipError, PointsError
18
- from pygeodesy.fmath import fabs, len2, Fsum
18
+ from pygeodesy.fmath import fabs, Fsum
19
19
  # from pygeodesy.fsums import Fsum # from .fmath
20
+ # from pygeodesy.internals import typename # from .basics
20
21
  from pygeodesy.interns import NN, _clipid_, _convex_, _DOT_, _end_, _few_, \
21
22
  _fi_, _height_, _i_, _invalid_, _j_, _lat_, \
22
23
  _lon_, _near_, _not_, _points_, _start_, _too_
@@ -30,7 +31,7 @@ from pygeodesy.units import Bool, FIx, HeightX, Lat, Lon, Number_
30
31
  # from math import fabs # from .fmath
31
32
 
32
33
  __all__ = _ALL_LAZY.clipy
33
- __version__ = '23.09.20'
34
+ __version__ = '25.04.14'
34
35
 
35
36
  _fj_ = 'fj'
36
37
  _original_ = 'original'
@@ -126,7 +127,7 @@ class _CS(_Named):
126
127
  # elif c & _CS._XR:
127
128
  # return self.lat4(p, self._xr)
128
129
  # # should never get here
129
- # raise _AssertionError(self._DOT_(self.clip4.__name__))
130
+ # raise _AssertionError(self._DOT_(typename(self.clip4)))
130
131
 
131
132
  def code4(self, p): # compute code for point p
132
133
  if p.lat < self._yb:
@@ -168,7 +169,7 @@ class _CS(_Named):
168
169
 
169
170
  def nop4(self, b, p): # PYCHOK no cover
170
171
  if p: # should never get here
171
- raise _AssertionError(self._DOT_(self.nop4.__name__))
172
+ raise _AssertionError(self._DOT_(typename(self.nop4)))
172
173
  return _CS._IN, self.nop4, b, p
173
174
 
174
175
 
@@ -202,7 +203,7 @@ def clipCS4(points, lowerleft, upperight, closed=False, inull=False):
202
203
  @raise PointsError: Insufficient number of B{C{points}}.
203
204
  '''
204
205
  T4 = ClipCS4Tuple
205
- cs = _CS(lowerleft, upperight, name=clipCS4.__name__)
206
+ cs = _CS(lowerleft, upperight, name=typename(clipCS4))
206
207
  n, pts = _pts2(points, closed, inull)
207
208
 
208
209
  i, m = _imdex2(closed, n)
@@ -398,7 +399,7 @@ def clipLB6(points, lowerleft, upperight, closed=False, inull=False):
398
399
  U{Liang-Barsky algorithm<https://WikiPedia.org/wiki/Liang-Barsky_algorithm>}.
399
400
  '''
400
401
  xl, yb, \
401
- xr, yt = _box4(lowerleft, upperight, clipLB6.__name__)
402
+ xr, yt = _box4(lowerleft, upperight, typename(clipLB6))
402
403
  n, pts = _pts2(points, closed, inull)
403
404
 
404
405
  T6 = ClipLB6Tuple
@@ -578,7 +579,7 @@ class _SH(_Named):
578
579
  fx = float(p2.lon - x)
579
580
  d = fy * dx - fx * dy # fdot((fx, fy), dx, -dy)
580
581
  if fabs(d) < EPS: # PYCHOK no cover
581
- raise _AssertionError(self._DOT_(self.intersect.__name__))
582
+ raise _AssertionError(self._DOT_(typename(self.intersect)))
582
583
  d = Fsum(self._xy, -y * dx, x * dy).fover(d)
583
584
  y += d * fy
584
585
  x += d * fx
@@ -644,7 +645,7 @@ def clipSH(points, corners, closed=False, inull=False):
644
645
 
645
646
  @raise PointsError: Insufficient number of B{C{points}}.
646
647
  '''
647
- sh = _SH(corners, name=clipSH.__name__)
648
+ sh = _SH(corners, name=typename(clipSH))
648
649
  n, pts = sh.clip2(points, closed, inull)
649
650
  for i in range(n):
650
651
  p, _ = sh.clipped2(pts[i])
@@ -671,7 +672,7 @@ def clipSH3(points, corners, closed=False, inull=False):
671
672
 
672
673
  @raise PointsError: Insufficient number of B{C{points}} or B{C{corners}}.
673
674
  '''
674
- sh = _SH(corners, name=clipSH3.__name__)
675
+ sh = _SH(corners, name=typename(clipSH3))
675
676
  n, pts = sh.clip2(points, closed, inull)
676
677
  if n > 1:
677
678
  T3 = ClipSH3Tuple
pygeodesy/constants.py CHANGED
@@ -13,8 +13,8 @@ from __future__ import division as _; del _ # PYCHOK semicolon
13
13
  from pygeodesy.basics import _copysign, isbool, iscomplex, isint
14
14
  from pygeodesy.errors import _xError, _xError2, _xkwds_get1, _xkwds_item2
15
15
  # from pygeodesy.fsums import _isFsum_2Tuple # _MODS
16
- from pygeodesy.internals import _0_0, _100_0
17
- from pygeodesy.interns import _INF_, _NAN_, _UNDER_
16
+ from pygeodesy.internals import _0_0, _100_0, typename
17
+ from pygeodesy.interns import _DMAIN_, _INF_, _NAN_
18
18
  from pygeodesy.lazily import _ALL_MODS as _MODS, _ALL_LAZY
19
19
  # from pygeodesy.streprs import Fmt # from .unitsBase
20
20
  from pygeodesy.unitsBase import Float, Int, Radius, Fmt
@@ -26,7 +26,7 @@ except ImportError: # Python 2-
26
26
  _inf, _nan = float(_INF_), float(_NAN_)
27
27
 
28
28
  __all__ = _ALL_LAZY.constants
29
- __version__ = '24.12.22'
29
+ __version__ = '25.04.14'
30
30
 
31
31
 
32
32
  def _copysign_0_0(y):
@@ -360,7 +360,7 @@ def isfinite(obj):
360
360
  return _iscfinite(obj)
361
361
  if _MODS.fsums._isFsum_2Tuple(obj): # OverflowError
362
362
  return obj.is_finite()
363
- raise _xError(x, Fmt.PAREN(isfinite.__name__, obj))
363
+ raise _xError(x, Fmt.PAREN(typename(isfinite), obj))
364
364
 
365
365
 
366
366
  def isint0(obj, both=False):
@@ -493,13 +493,14 @@ def _umod_PI2(rad):
493
493
  return (rad % PI2) or _0_0
494
494
 
495
495
 
496
- if __name__ == '__main__':
496
+ if __name__ == _DMAIN_:
497
497
 
498
- def _main():
498
+ def _main(locals):
499
499
  from pygeodesy import itemsorted, printf
500
+ from pygeodesy.interns import _DALL_, _UNDER_
500
501
 
501
502
  t = n = v = []
502
- for n, v in itemsorted(locals()):
503
+ for n, v in itemsorted(locals):
503
504
  if isinstance(v, (Float, Int, Radius)):
504
505
  printf('%9s: %r', n, v.toRepr(std=False))
505
506
  if v.name != n:
@@ -508,10 +509,10 @@ if __name__ == '__main__':
508
509
  raise AssertionError('%r is not %r' % (n, v))
509
510
  if not n.startswith(_UNDER_):
510
511
  t.append(n)
511
- t.append(float_.__name__)
512
- printf('__all__ = %r', tuple(t))
512
+ t.append(typename(float_))
513
+ printf('%s = %r', _DALL_, tuple(t))
513
514
 
514
- _main()
515
+ _main(locals())
515
516
 
516
517
  # **) MIT License
517
518
  #
pygeodesy/css.py CHANGED
@@ -3,12 +3,13 @@
3
3
 
4
4
  u'''Cassini-Soldner (CSS) projection.
5
5
 
6
- Classes L{CassiniSoldner}, L{Css} and L{CSSError} requiring I{Charles Karney}'s
7
- U{geographiclib <https://PyPI.org/project/geographiclib>} Python package to be
8
- installed.
6
+ Classes L{CassiniSoldner}, L{Css} and L{CSSError} use I{Charles Karney}'s
7
+ U{geographiclib <https://PyPI.org/project/geographiclib>} Python package
8
+ if installed, see property L{CassiniSoldner.geodesic}.
9
9
  '''
10
10
 
11
- from pygeodesy.basics import islistuple, neg, _xinstanceof, _xsubclassof
11
+ from pygeodesy.basics import _isin, islistuple, neg, _xinstanceof, \
12
+ _xsubclassof
12
13
  from pygeodesy.constants import _umod_360, _0_0, _0_5, _90_0
13
14
  from pygeodesy.datums import _ellipsoidal_datum, _WGS84
14
15
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
@@ -33,7 +34,7 @@ from pygeodesy.units import Azimuth, Degrees, Easting, Height, _heigHt, \
33
34
  # from math import fabs # from .karney
34
35
 
35
36
  __all__ = _ALL_LAZY.css
36
- __version__ = '24.11.06'
37
+ __version__ = '25.04.14'
37
38
 
38
39
 
39
40
  def _CS0(cs0):
@@ -76,7 +77,7 @@ class CassiniSoldner(_NamedBase):
76
77
 
77
78
  @raise CSSError: Invalid B{C{lat}} or B{C{lon}}.
78
79
  '''
79
- if datum not in (None, self._datum):
80
+ if not _isin(datum, None, self._datum):
80
81
  self._datum = _xellipsoidal(datum=_ellipsoidal_datum(datum, **name))
81
82
  if name:
82
83
  self.name = name
@@ -217,9 +218,10 @@ class CassiniSoldner(_NamedBase):
217
218
  @Property
218
219
  def geodesic(self):
219
220
  '''Get this projection's I{wrapped} U{geodesic.Geodesic
220
- <https://GeographicLib.SourceForge.io/Python/doc/code.html>}, provided
221
+ <https://GeographicLib.SourceForge.io/Python/doc/code.html>} from
221
222
  I{Karney}'s U{geographiclib<https://PyPI.org/project/geographiclib>}
222
- package is installed, otherwise an I{exact} L{GeodesicExact} instance.
223
+ package if installed, otherwise an I{exact} L{GeodesicExact
224
+ <pygeodesy.geodesicx.GeodesicExact>} instance.
223
225
  '''
224
226
  g = self._geodesic
225
227
  if g is None:
@@ -247,7 +249,8 @@ class CassiniSoldner(_NamedBase):
247
249
 
248
250
  @Property_RO
249
251
  def isExact(self):
250
- '''Return C{True} if this projection's geodesic is L{GeodesicExact}.
252
+ '''Return C{True} if this projection's geodesic is L{GeodesicExact
253
+ <pygeodesy.geodesicx.GeodesicExact>}.
251
254
  '''
252
255
  return isinstance(self.geodesic, _MODS.geodesicx.GeodesicExact)
253
256
 
@@ -306,8 +309,8 @@ class CassiniSoldner(_NamedBase):
306
309
 
307
310
  g = self.geodesic
308
311
  self._meridian = m = g.Line(Lat_(lat0=lat0, Error=CSSError),
309
- Lon_(lon0=lon0, Error=CSSError), _0_0,
310
- g.STANDARD | g.DISTANCE_IN | g.LINE_OFF)
312
+ Lon_(lon0=lon0, Error=CSSError),
313
+ _0_0, caps=g.STANDARD_LINE | g.LINE_OFF)
311
314
  self._latlon0 = LatLon2Tuple(m.lat1, m.lon1)
312
315
  s, c = _sincos2d(m.lat1) # == self.lat0 == self.LatitudeOrigin()
313
316
  self._sb0, self._cb0 = _norm2(s * g.f1, c)