pygeodesy 24.5.15__py2.py3-none-any.whl → 24.6.1__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 (90) hide show
  1. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
  2. PyGeodesy-24.6.1.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +4 -4
  4. pygeodesy/albers.py +41 -41
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/__main__.py +2 -2
  7. pygeodesy/auxilats/auxAngle.py +32 -31
  8. pygeodesy/auxilats/auxLat.py +80 -51
  9. pygeodesy/azimuthal.py +123 -124
  10. pygeodesy/basics.py +46 -10
  11. pygeodesy/booleans.py +13 -14
  12. pygeodesy/cartesianBase.py +25 -23
  13. pygeodesy/clipy.py +3 -3
  14. pygeodesy/constants.py +3 -3
  15. pygeodesy/css.py +50 -42
  16. pygeodesy/datums.py +42 -41
  17. pygeodesy/deprecated/functions.py +9 -3
  18. pygeodesy/dms.py +6 -6
  19. pygeodesy/ecef.py +41 -41
  20. pygeodesy/ellipsoidalBase.py +41 -41
  21. pygeodesy/ellipsoidalBaseDI.py +3 -4
  22. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  23. pygeodesy/ellipsoidalKarney.py +3 -3
  24. pygeodesy/ellipsoidalNvector.py +11 -12
  25. pygeodesy/ellipsoids.py +45 -38
  26. pygeodesy/elliptic.py +3 -4
  27. pygeodesy/epsg.py +4 -3
  28. pygeodesy/errors.py +52 -20
  29. pygeodesy/etm.py +68 -65
  30. pygeodesy/fmath.py +44 -49
  31. pygeodesy/formy.py +129 -115
  32. pygeodesy/frechet.py +118 -103
  33. pygeodesy/fstats.py +21 -14
  34. pygeodesy/fsums.py +124 -80
  35. pygeodesy/gars.py +10 -9
  36. pygeodesy/geodesicw.py +19 -17
  37. pygeodesy/geodesicx/__init__.py +1 -1
  38. pygeodesy/geodesicx/__main__.py +2 -2
  39. pygeodesy/geodesicx/gx.py +39 -33
  40. pygeodesy/geodesicx/gxarea.py +12 -9
  41. pygeodesy/geodesicx/gxbases.py +3 -4
  42. pygeodesy/geodesicx/gxline.py +6 -8
  43. pygeodesy/geodsolve.py +29 -28
  44. pygeodesy/geohash.py +60 -57
  45. pygeodesy/geoids.py +34 -32
  46. pygeodesy/hausdorff.py +114 -101
  47. pygeodesy/heights.py +137 -130
  48. pygeodesy/internals.py +16 -11
  49. pygeodesy/interns.py +3 -6
  50. pygeodesy/iters.py +19 -17
  51. pygeodesy/karney.py +21 -17
  52. pygeodesy/ktm.py +25 -18
  53. pygeodesy/latlonBase.py +12 -11
  54. pygeodesy/lazily.py +6 -6
  55. pygeodesy/lcc.py +24 -25
  56. pygeodesy/ltp.py +143 -113
  57. pygeodesy/ltpTuples.py +207 -150
  58. pygeodesy/mgrs.py +26 -26
  59. pygeodesy/named.py +172 -90
  60. pygeodesy/namedTuples.py +33 -25
  61. pygeodesy/nvectorBase.py +8 -8
  62. pygeodesy/osgr.py +40 -48
  63. pygeodesy/points.py +18 -18
  64. pygeodesy/props.py +29 -16
  65. pygeodesy/rhumb/__init__.py +1 -1
  66. pygeodesy/rhumb/aux_.py +13 -15
  67. pygeodesy/rhumb/bases.py +12 -5
  68. pygeodesy/rhumb/ekx.py +24 -18
  69. pygeodesy/rhumb/solve.py +13 -10
  70. pygeodesy/simplify.py +16 -16
  71. pygeodesy/solveBase.py +18 -18
  72. pygeodesy/sphericalBase.py +17 -21
  73. pygeodesy/sphericalTrigonometry.py +21 -21
  74. pygeodesy/streprs.py +5 -5
  75. pygeodesy/trf.py +13 -11
  76. pygeodesy/triaxials.py +68 -64
  77. pygeodesy/units.py +35 -35
  78. pygeodesy/unitsBase.py +24 -11
  79. pygeodesy/ups.py +66 -70
  80. pygeodesy/utily.py +3 -3
  81. pygeodesy/utm.py +183 -187
  82. pygeodesy/utmups.py +38 -38
  83. pygeodesy/utmupsBase.py +104 -106
  84. pygeodesy/vector2d.py +6 -7
  85. pygeodesy/vector3d.py +16 -17
  86. pygeodesy/vector3dBase.py +4 -5
  87. pygeodesy/webmercator.py +43 -51
  88. PyGeodesy-24.5.15.dist-info/RECORD +0 -116
  89. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
  90. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/internals.py CHANGED
@@ -3,11 +3,11 @@
3
3
  u'''Mostly INTERNAL functions, except L{machine}, L{print_} and L{printf}.
4
4
  '''
5
5
  # from pygeodesy.basics import isiterablen # _MODS
6
- # from pygeodesy.errors import _AttributeError, _error_init, _xError2 # _MODS
6
+ # from pygeodesy.errors import _AttributeError, _error_init, _UnexpectedError, _xError2 # _MODS
7
7
  from pygeodesy.interns import NN, _COLON_, _DOT_, _ELLIPSIS_, _EQUALSPACED_, \
8
8
  _immutable_, _NL_, _pygeodesy_, _PyPy__, _python_, \
9
- _QUOTE1_, _QUOTE2_, _SPACE_, _UNDER_, _utf_8_
10
- from pygeodesy.interns import _COMMA_, _sys, _Python_ # PYCHOK used!
9
+ _QUOTE1_, _QUOTE2_, _s_, _SPACE_, _sys, _UNDER_, _utf_8_
10
+ from pygeodesy.interns import _COMMA_, _Python_ # PYCHOK used!
11
11
  # from pygeodesy.streprs import anstr, pairs, unstr # _MODS
12
12
 
13
13
  import os as _os # in .lazily, ...
@@ -222,7 +222,7 @@ def _caller3(up): # in .lazily, .named
222
222
  f.f_lineno) # line number
223
223
 
224
224
 
225
- def _dunder_main(name):
225
+ def _dunder_ismain(name):
226
226
  '''(INTERNAL) Return C{name == '__main__'}.
227
227
  '''
228
228
  return name == '__main__'
@@ -353,6 +353,12 @@ def _passargs(*args):
353
353
  return args
354
354
 
355
355
 
356
+ def _plural(noun, n):
357
+ '''(INTERNAL) Return C{noun}['s'] or C{NN}.
358
+ '''
359
+ return NN(noun, _s_) if n > 1 else (noun if n else NN)
360
+
361
+
356
362
  def print_(*args, **nl_nt_prec_prefix__end_file_flush_sep_kwds): # PYCHOK no cover
357
363
  '''Python 3+ C{print}-like formatting and printing.
358
364
 
@@ -497,7 +503,7 @@ def _usage(file_py, *args): # in .etm
497
503
  m = _os_path.dirname(file_py).replace(_os.getcwd(), _ELLIPSIS_) \
498
504
  .replace(_os.sep, _DOT_).strip()
499
505
  b, x = _os_path.splitext(_os_path.basename(file_py))
500
- if x == '.py' and not _dunder_main(b):
506
+ if x == '.py' and not _dunder_ismain(b):
501
507
  m = _DOT_(m or _pygeodesy_, b)
502
508
  p = NN(_python_, _sys.version_info[0])
503
509
  u = _COLON_(_dunder_nameof(_usage)[1:], NN)
@@ -536,17 +542,16 @@ def _version_ints(vs):
536
542
  return tuple(_ints(vs))
537
543
 
538
544
 
539
- __all__ = (machine.__name__,
540
- print_.__name__, printf.__name__) # _dunder_nameof
541
- __version__ = '24.05.15'
545
+ __all__ = tuple(map(_dunder_nameof, (machine, print_, printf)))
546
+ __version__ = '24.05.25'
542
547
 
543
- if _dunder_main(__name__): # PYCHOK no cover
548
+ if _dunder_ismain(__name__): # PYCHOK no cover
544
549
 
545
550
  from pygeodesy import _isfrozen, isLazy, version as vs
546
551
 
547
552
  print_(_pygeodesy_, vs, *(_Pythonarchine() + _osversion2()
548
- + ['isfrozen', _isfrozen,
549
- 'isLazy', isLazy]))
553
+ + ['_isfrozen', _isfrozen,
554
+ 'isLazy', isLazy]))
550
555
 
551
556
  # **) MIT License
552
557
  #
pygeodesy/interns.py CHANGED
@@ -201,11 +201,10 @@ _distance_ = 'distance' # PYCHOK OK
201
201
  _distant_ = _Prefix('distant') # PYCHOK OK
202
202
  _doesn_t_exist_ = "doesn't exist" # PYCHOK OK
203
203
  _DOT_ = Str_('.') # PYCHOK OK
204
- _down_ = 'down' # PYCHOK OK
204
+ _dunder_name_ = '__name__' # PYCHOK _DUNDER_(NN, _name_, NN)
205
205
  _e_ = 'e' # PYCHOK OK
206
206
  _E_ = 'E' # PYCHOK OK
207
207
  _earth_ = 'earth' # PYCHOK OK
208
- _east_ = 'east' # PYCHOK OK
209
208
  _easting_ = 'easting' # PYCHOK OK
210
209
  _ecef_ = 'ecef' # PYCHOK OK
211
210
  _edge_ = 'edge' # PYCHOK OK
@@ -259,8 +258,8 @@ _isclockwise_ = 'isclockwise' # PYCHOK OK
259
258
  _ispolar_ = 'ispolar' # PYCHOK OK
260
259
  _j_ = 'j' # PYCHOK OK
261
260
  _k0_ = 'k0' # PYCHOK OK
261
+ _keyword_ = 'keyword' # PYCHOK OK
262
262
  _kind_ = 'kind' # PYCHOK OK
263
- _knots_ = 'knots' # PYCHOK OK
264
263
  _Krassovski1940_ = 'Krassovski1940' # PYCHOK OK
265
264
  _Krassowsky1940_ = 'Krassowsky1940' # PYCHOK OK
266
265
  _LANGLE_ = '<' # PYCHOK OK
@@ -317,7 +316,6 @@ _NLHASH_ = Str_(_NL_ + '# ') # PYCHOK OK
317
316
  # _NLNL_ = _DNL_ # PYCHOK OK
318
317
  _NN_ = 'NN' # PYCHOK OK
319
318
  _no_ = _Prefix('no') # PYCHOK OK
320
- _north_ = 'north' # PYCHOK OK
321
319
  _northing_ = 'northing' # PYCHOK OK
322
320
  _NorthPole_ = 'NorthPole' # PYCHOK OK
323
321
  _not_ = _Prefix('not') # PYCHOK OK
@@ -394,7 +392,6 @@ _STAR_ = Str_('*') # PYCHOK OK
394
392
  _start_ = 'start' # PYCHOK OK
395
393
  _std_ = 'std' # PYCHOK OK
396
394
  _stdev_ = 'stdev' # PYCHOK OK
397
- _supported_ = 'supported' # PYCHOK OK
398
395
  _tbd_ = 'tbd' # PYCHOK OK
399
396
  _TILDE_ = '~' # PYCHOK OK
400
397
  _to_ = 'to' # PYCHOK OK
@@ -450,7 +447,7 @@ _LR_PAIRS = {_LANGLE_: _RANGLE_,
450
447
 
451
448
  __all__ = (_NN_, # NOT MISSING!
452
449
  Str_.__name__) # classes
453
- __version__ = '24.05.13'
450
+ __version__ = '24.05.21'
454
451
 
455
452
  if __name__ == '__main__':
456
453
 
pygeodesy/iters.py CHANGED
@@ -15,10 +15,10 @@ from pygeodesy.basics import islistuple, issubclassof, len2, \
15
15
  from pygeodesy.errors import _IndexError, LenError, PointsError, \
16
16
  _TypeError, _ValueError
17
17
  # from pygeodesy.internals import _passarg # from .basics
18
- from pygeodesy.interns import NN, _0_, _composite_, _few_, \
19
- _latlon_, _points_, _too_
18
+ from pygeodesy.interns import _0_, _composite_, _few_, _latlon_, \
19
+ _points_, _too_
20
20
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
21
- from pygeodesy.named import Fmt, _Named, property_RO
21
+ from pygeodesy.named import _Named, property_RO, Fmt
22
22
  from pygeodesy.namedTuples import Point3Tuple, Points2Tuple
23
23
  # from pygeodesy.props import property_RO # from .named
24
24
  # from pygeodesy.streprs import Fmt # from .named
@@ -26,7 +26,7 @@ from pygeodesy.units import Int, Radius
26
26
  from pygeodesy.utily import degrees2m, _Wrap, _1_0
27
27
 
28
28
  __all__ = _ALL_LAZY.iters
29
- __version__ = '23.12.14'
29
+ __version__ = '24.05.23'
30
30
 
31
31
  _items_ = 'items'
32
32
  _iterNumpy2len = 1 # adjustable for testing purposes
@@ -50,7 +50,7 @@ class _BaseIter(_Named):
50
50
  _prev = _NOTHING
51
51
  _wrap = False
52
52
 
53
- def __init__(self, items, loop=0, dedup=False, Error=None, name=NN):
53
+ def __init__(self, items, loop=0, dedup=False, Error=None, **name):
54
54
  '''New iterator over an iterable of B{C{items}}.
55
55
 
56
56
  @arg items: Iterable (any C{type}, except composites).
@@ -58,7 +58,7 @@ class _BaseIter(_Named):
58
58
  iterate index (non-negative C{int}).
59
59
  @kwarg dedup: Skip duplicate items (C{bool}).
60
60
  @kwarg Error: Error to raise (L{LenError}).
61
- @kwarg name: Optional name (C{str}).
61
+ @kwarg name: Optional C{B{name}="items"} (C{str}).
62
62
 
63
63
  @raise Error: Invalid B{C{items}} or sufficient number of B{C{items}}.
64
64
 
@@ -238,10 +238,11 @@ class _BaseIter(_Named):
238
238
  class PointsIter(_BaseIter):
239
239
  '''Iterator for C{points} with optional loop-back and copies.
240
240
  '''
241
- _base = None
242
- _Error = PointsError
241
+ _base = None
242
+ _Error = PointsError
243
+ _name = _points_
243
244
 
244
- def __init__(self, points, loop=0, base=None, dedup=False, wrap=False, name=NN):
245
+ def __init__(self, points, loop=0, base=None, dedup=False, wrap=False, **name):
245
246
  '''New L{PointsIter} iterator.
246
247
 
247
248
  @arg points: C{Iterable} or C{list}, C{sequence}, C{set}, C{tuple},
@@ -252,13 +253,13 @@ class PointsIter(_BaseIter):
252
253
  @kwarg dedup: Skip duplicate points (C{bool}).
253
254
  @kwarg wrap: If C{True}, wrap or I{normalize} the enum-/iterated
254
255
  B{C{points}} (C{bool}).
255
- @kwarg name: Optional name (C{str}).
256
+ @kwarg name: Optional C{B{name}="points"} (C{str}).
256
257
 
257
258
  @raise PointsError: Insufficient number of B{C{points}}.
258
259
 
259
260
  @raise TypeError: Some B{C{points}} are not B{C{base}}.
260
261
  '''
261
- _BaseIter.__init__(self, points, loop=loop, dedup=dedup, name=name or _points_)
262
+ _BaseIter.__init__(self, points, loop=loop, dedup=dedup, **name)
262
263
 
263
264
  if base and not (isNumpy2(points) or isTuple2(points)):
264
265
  self._base = base
@@ -310,12 +311,13 @@ class PointsIter(_BaseIter):
310
311
  class LatLon2PsxyIter(PointsIter):
311
312
  '''Iterate and convert for C{points} with optional loop-back and copies.
312
313
  '''
313
- _deg2m = None
314
- _radius = None # keep degrees
315
- _wrap = True
314
+ _deg2m = None
315
+ _name = _latlon_
316
+ _radius = None # keep degrees
317
+ _wrap = True
316
318
 
317
319
  def __init__(self, points, loop=0, base=None, wrap=True, radius=None,
318
- dedup=False, name=_latlon_):
320
+ dedup=False, **name):
319
321
  '''New L{LatLon2PsxyIter} iterator.
320
322
 
321
323
  @note: The C{LatLon} latitude is considered the I{pseudo-y} and
@@ -331,13 +333,13 @@ class LatLon2PsxyIter(PointsIter):
331
333
  @kwarg radius: Mean earth radius (C{meter}) for conversion from
332
334
  C{degrees} to C{meter} (or C{radians} if C{B{radius}=1}).
333
335
  @kwarg dedup: Skip duplicate points (C{bool}).
334
- @kwarg name: Optional name (C{str}).
336
+ @kwarg name: Optional C{B{name}="latlon"} (C{str}).
335
337
 
336
338
  @raise PointsError: Insufficient number of B{C{points}}.
337
339
 
338
340
  @raise TypeError: Some B{C{points}} are not B{C{base}}-compatible.
339
341
  '''
340
- PointsIter.__init__(self, points, loop=loop, base=base, dedup=dedup, name=name)
342
+ PointsIter.__init__(self, points, loop=loop, base=base, dedup=dedup, **name)
341
343
  if not wrap:
342
344
  self._wrap = False
343
345
  if radius:
pygeodesy/karney.py CHANGED
@@ -142,13 +142,14 @@ from __future__ import division as _; del _ # PYCHOK semicolon
142
142
  from pygeodesy.basics import _copysign, int1s, isint, itemsorted, neg, unsigned0, \
143
143
  _xgeographiclib, _zip, _version_info
144
144
  from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
145
- _1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
146
- from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get
145
+ _1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
146
+ from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
147
147
  from pygeodesy.fmath import cbrt, fremainder, norm2
148
148
  # from pygeodesy.internals import _version_info # from .basics
149
- from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi2_, _azi12_, _composite_, \
150
- _lat1_, _lat2_, _lon1_, _lon2_, _m12_, _M12_, _M21_, \
151
- _number_, _s12_, _S12_, _UNDER_, _BAR_ # PYCHOK used!
149
+ from pygeodesy.interns import _2_, _a12_, _area_, _azi2_, _azi12_, _composite_, \
150
+ _lat1_, _lat2_, _lon1_, _lon2_, _m12_, _M12_, \
151
+ _M21_, _number_, _s12_, _S12_, _UNDER_, \
152
+ _BAR_, NN # PYCHOK used!
152
153
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
153
154
  from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
154
155
  from pygeodesy.props import deprecated_method, Property_RO
@@ -159,7 +160,7 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
159
160
  # from math import fabs # from .utily
160
161
 
161
162
  __all__ = _ALL_LAZY.karney
162
- __version__ = '24.05.13'
163
+ __version__ = '24.05.31'
163
164
 
164
165
  _K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
165
166
  _perimeter_ = 'perimeter'
@@ -168,10 +169,10 @@ _perimeter_ = 'perimeter'
168
169
  class _GTuple(_NamedTuple): # in .testNamedTuples
169
170
  '''(INTERNAL) Helper.
170
171
  '''
171
- def toGDict(self, **updates):
172
+ def toGDict(self, **updates): # NO name=NN
172
173
  '''Convert this C{*Tuple} to a L{GDict}.
173
174
 
174
- @kwarg updates: Optional items to apply (C{nam=value} pairs)
175
+ @kwarg updates: Optional items to apply (C{name=value} pairs)
175
176
  '''
176
177
  r = GDict(_zip(self._Names_, self)) # strict=True
177
178
  if updates:
@@ -359,12 +360,11 @@ class _CapsBase(_NamedBase): # in .auxilats, .geodesicx.gxbases
359
360
  '''
360
361
  self._debug = Caps._DEBUG_ALL if debug else 0
361
362
 
362
- def _iter2tion(self, r, s):
363
+ def _iter2tion(self, r, iter=None, **unused):
363
364
  '''(INTERNAL) Copy C{C{s}.iter} into C{B{r}._iteration}.
364
365
  '''
365
- i = _xkwds_get(s, iter=None)
366
- if i is not None:
367
- self._iteration = r._iteration = i
366
+ if iter is not None:
367
+ self._iteration = r._iteration = iter
368
368
  return r
369
369
 
370
370
 
@@ -468,7 +468,7 @@ class Inverse10Tuple(_GTuple):
468
468
 
469
469
  @kwarg updates: Optional items to apply (C{nam=value} pairs)
470
470
  '''
471
- return _GTuple.toGDict(self, azi1=atan2d(self.salp1, self.calp1), # PYCHOK indent, namedTuple
471
+ return _GTuple.toGDict(self, azi1=atan2d(self.salp1, self.calp1), # PYCHOK namedTuple
472
472
  azi2=atan2d(self.salp2, self.calp2), # PYCHOK namedTuple
473
473
  **updates) # PYCHOK indent
474
474
 
@@ -750,7 +750,10 @@ def _polynomial(x, cs, i, j): # PYCHOK shared
750
750
  # for c in cs[i+1:j]:
751
751
  # s, t = _sum2_(s * x, t * x, c)
752
752
  # return s # + t
753
- s, _ = _sum2_(cs[i], _0_0, x=x, *cs[i+1:j])
753
+ s = cs[i]
754
+ i += 1
755
+ if x and i < j:
756
+ s, _ = _sum2_(s, _0_0, x=x, *cs[i:j])
754
757
  return s # + t
755
758
 
756
759
 
@@ -843,11 +846,12 @@ def _sum2_(s, t, *vs, **x):
843
846
 
844
847
  @note: NOT "error-free", see C{pygeodesy.test/testKarney.py}.
845
848
  '''
846
- x = _xkwds_get(x, x=0)
849
+ x = _xkwds_get1(x, x=_1_0)
850
+ p = x != _1_0
847
851
 
848
852
  _s2, _u0 = _sum2, unsigned0
849
853
  for v in vs:
850
- if x:
854
+ if p:
851
855
  s *= x
852
856
  t *= x
853
857
  if v:
@@ -857,7 +861,7 @@ def _sum2_(s, t, *vs, **x):
857
861
  if s:
858
862
  t += u # accumulate u into t
859
863
  # elif t: # s == 0 implies t == 0
860
- # raise _AssertionError(t=t, txt=_not_(_0_))
864
+ # raise _AssertionError(t=t, txt_not_=_0_)
861
865
  else:
862
866
  s = _u0(u) # result is u, t = 0
863
867
  else:
pygeodesy/ktm.py CHANGED
@@ -48,10 +48,10 @@ from pygeodesy.constants import INF, _K0_UTM, PI, PI_2, _0_0s, _0_0, \
48
48
  _1_0, _90_0, _copysignINF
49
49
  from pygeodesy.datums import Datum, _spherical_datum, _WGS84, _EWGS84
50
50
  # from pygeodesy.ellipsoids import _EWGS84 # from .datums
51
- from pygeodesy.errors import _ValueError, _xkwds_get, _Xorder
51
+ from pygeodesy.errors import _ValueError, _xkwds_pop2, _Xorder
52
52
  from pygeodesy.fmath import hypot, hypot1
53
53
  from pygeodesy.fsums import fsum1f_
54
- from pygeodesy.interns import NN, _COMMASPACE_, _singular_
54
+ from pygeodesy.interns import _COMMASPACE_, _singular_
55
55
  from pygeodesy.karney import _atan2d, _diff182, _fix90, _norm180, \
56
56
  _polynomial, _unsigned2
57
57
  # from pygeodesy.lazily import _ALL_LAZY # from .named
@@ -67,7 +67,7 @@ from cmath import polar
67
67
  from math import atan2, asinh, cos, cosh, degrees, fabs, sin, sinh, sqrt, tanh
68
68
 
69
69
  __all__ = _ALL_LAZY.ktm
70
- __version__ = '24.05.11'
70
+ __version__ = '24.05.24'
71
71
 
72
72
 
73
73
  class KTMError(_ValueError):
@@ -115,24 +115,33 @@ class KTransverseMercator(_NamedBase):
115
115
  _mTM = 6
116
116
  _raiser = False # throw Error
117
117
 
118
- def __init__(self, a_earth=_EWGS84, f=None, lon0=0, k0=_K0_UTM, name=NN,
119
- raiser=False, **TMorder):
118
+ def __init__(self, a_earth=_EWGS84, f=None, lon0=0, k0=_K0_UTM,
119
+ raiser=False, **TMorder_name):
120
120
  '''New L{KTransverseMercator}.
121
121
 
122
122
  @kwarg a_earth: This rhumb's earth (L{Ellipsoid}, L{Ellipsoid2},
123
123
  L{a_f2Tuple}, L{Datum}, 2-tuple (C{a, f})) or the
124
124
  equatorial radius (C{scalar}, C{meter}).
125
- @kwarg f: The ellipsoid's flattening (C{scalar}), iff B{C{a_earth}} is
126
- a C{scalar}, ignored otherwise.
125
+ @kwarg f: The ellipsoid's flattening (C{scalar}), iff B{C{a_earth}}
126
+ is a C{scalar}, ignored otherwise.
127
127
  @kwarg lon0: The central meridian (C{degrees180}).
128
128
  @kwarg k0: Central scale factor (C{scalar}).
129
- @kwarg name: Optional name (C{str}).
130
129
  @kwarg raiser: If C{True}, throw a L{KTMError} for C{forward}
131
130
  singularities (C{bool}).
132
- @kwarg TMorder: Keyword argument B{C{TMorder}}, see property C{TMorder}.
131
+ @kwarg TMorder_name: Optional C{B{name}=NN} (C{str}) and optional
132
+ keyword argument C{B{TMorder}=6} for the order of
133
+ this L{KTransverseMercator}, see property C{TMorder}.
133
134
 
134
135
  @raise KTMError: Invalid B{C{a_earth}}, B{C{f}} or B{C{TMorder}}.
135
136
  '''
137
+ if TMorder_name:
138
+ M = self._mTM
139
+ m, name = _xkwds_pop2(TMorder_name, TMorder=M)
140
+ if m != M:
141
+ self.TMorder = m
142
+ if name:
143
+ self.name = name
144
+
136
145
  if f is not None:
137
146
  self.ellipsoid = a_earth, f
138
147
  elif a_earth in (_EWGS84, _WGS84, None):
@@ -141,14 +150,11 @@ class KTransverseMercator(_NamedBase):
141
150
  self.datum = a_earth
142
151
  else:
143
152
  self.ellipsoid = a_earth
153
+
144
154
  self.lon0 = lon0
145
155
  self.k0 = k0
146
- if name: # PYCHOK no cover
147
- self.name = name
148
156
  if raiser:
149
157
  self.raiser = True
150
- if TMorder:
151
- self.TMorder = _xkwds_get(TMorder, TMorder=self._mTM)
152
158
 
153
159
  @Property_RO
154
160
  def _Alp(self):
@@ -215,13 +221,13 @@ class KTransverseMercator(_NamedBase):
215
221
 
216
222
  f = flattening
217
223
 
218
- def forward(self, lat, lon, lon0=None, name=NN):
224
+ def forward(self, lat, lon, lon0=None, **name):
219
225
  '''Forward projection, from geographic to transverse Mercator.
220
226
 
221
227
  @arg lat: Latitude of point (C{degrees90}).
222
228
  @arg lon: Longitude of point (C{degrees180}).
223
229
  @arg lon0: Central meridian of the projection (C{degrees180}).
224
- @kwarg name: Optional name (C{str}).
230
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
225
231
 
226
232
  @return: L{Forward4Tuple}C{(easting, northing, gamma, scale)}
227
233
  with C{easting} and C{northing} in C{meter}, unfalsed, the
@@ -272,7 +278,7 @@ class KTransverseMercator(_NamedBase):
272
278
  y, g = neg_(y, g)
273
279
  if _lon:
274
280
  x, g = neg_(x, g)
275
- return Forward4Tuple(x, y, _norm180(g), k, name=name or self.name)
281
+ return Forward4Tuple(x, y, _norm180(g), k, name=self._name__(name))
276
282
 
277
283
  @property_doc_(''' the central scale factor (C{float}).''')
278
284
  def k0(self):
@@ -347,12 +353,13 @@ class KTransverseMercator(_NamedBase):
347
353
  self. lon0 = lon0
348
354
  return t
349
355
 
350
- def reverse(self, x, y, lon0=None, name=NN):
356
+ def reverse(self, x, y, lon0=None, **name):
351
357
  '''Reverse projection, from transverse Mercator to geographic.
352
358
 
353
359
  @arg x: Easting of point (C{meter}).
354
360
  @arg y: Northing of point (C{meter}).
355
361
  @arg lon0: Central meridian of the projection (C{degrees180}).
362
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
356
363
 
357
364
  @return: L{Reverse4Tuple}C{(lat, lon, gamma, scale)} with
358
365
  C{lat}- and C{lon}gitude in C{degrees}, I{unfalsed}.
@@ -394,7 +401,7 @@ class KTransverseMercator(_NamedBase):
394
401
  lat += self._lat0
395
402
  lon += self._lon0 if lon0 is None else _norm180(lon0)
396
403
  return Reverse4Tuple(lat, _norm180(lon), _norm180(g), k,
397
- name=name or self.name)
404
+ name=self._name__(name))
398
405
 
399
406
  @Property
400
407
  def TMorder(self):
pygeodesy/latlonBase.py CHANGED
@@ -53,7 +53,7 @@ from contextlib import contextmanager
53
53
  from math import asin, cos, degrees, fabs, radians
54
54
 
55
55
  __all__ = _ALL_LAZY.latlonBase
56
- __version__ = '24.04.07'
56
+ __version__ = '24.05.18'
57
57
 
58
58
 
59
59
  class LatLonBase(_NamedBase):
@@ -66,7 +66,7 @@ class LatLonBase(_NamedBase):
66
66
  _lat = 0 # latitude (C{degrees})
67
67
  _lon = 0 # longitude (C{degrees})
68
68
 
69
- def __init__(self, latlonh, lon=None, height=0, wrap=False, name=NN, datum=None):
69
+ def __init__(self, latlonh, lon=None, height=0, wrap=False, datum=None, **name):
70
70
  '''New C{LatLon}.
71
71
 
72
72
  @arg latlonh: Latitude (C{degrees} or DMS C{str} with N or S suffix) or
@@ -77,9 +77,9 @@ class LatLonBase(_NamedBase):
77
77
  (C{meter}, conventionally).
78
78
  @kwarg wrap: If C{True}, wrap or I{normalize} B{C{lat}} and B{C{lon}}
79
79
  (C{bool}).
80
- @kwarg name: Optional name (C{str}).
81
80
  @kwarg datum: Optional datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
82
81
  L{a_f2Tuple} or I{scalar} radius) or C{None}.
82
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
83
83
 
84
84
  @return: New instance (C{LatLon}).
85
85
 
@@ -1418,13 +1418,14 @@ class LatLonBase(_NamedBase):
1418
1418
  for p in (p, c):
1419
1419
  e = _xattr(p, Ecef=None)
1420
1420
  if e not in (None, E): # PYCHOK no cover
1421
- n = Fmt.INDEX(_xkwds_item2(name_point)[0], i)
1422
- raise _ValueError(n, e, txt=_incompatible(E.__name__))
1421
+ n, _ = _xkwds_item2(name_point)
1422
+ n = Fmt.INDEX(n, i)
1423
+ raise _ValueError(n, e, txt=_incompatible(E.__name__)) # txt__
1423
1424
  return c
1424
1425
 
1425
- def toDatum(self, datum2, height=None, name=NN):
1426
+ def toDatum(self, datum2, height=None, **name):
1426
1427
  '''I{Must be overloaded}.'''
1427
- self._notOverloaded(datum2, height=height, name=name)
1428
+ self._notOverloaded(datum2, height=height, **name)
1428
1429
 
1429
1430
  def toEcef(self, height=None, M=False):
1430
1431
  '''Convert this point to I{geocentric} coordinates, also known as
@@ -1476,16 +1477,16 @@ class LatLonBase(_NamedBase):
1476
1477
  return self._Ltp if Ecef in (None, self.Ecef) else self._ltp.Ltp(
1477
1478
  self, ecef=Ecef(self.datum), name=self.name)
1478
1479
 
1479
- def toNormal(self, deep=False, name=NN):
1480
+ def toNormal(self, deep=False, **name):
1480
1481
  '''Get this point I{normalized} to C{abs(lat) <= 90}
1481
1482
  and C{abs(lon) <= 180}.
1482
1483
 
1483
1484
  @kwarg deep: If C{True} make a deep, otherwise a
1484
1485
  shallow copy (C{bool}).
1485
- @kwarg name: Optional name of the copy (C{str}).
1486
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1486
1487
 
1487
- @return: A copy of this point, I{normalized} and
1488
- optionally renamed (C{LatLon}).
1488
+ @return: A copy of this point, I{normalized} (C{LatLon}),
1489
+ optionally renamed.
1489
1490
 
1490
1491
  @see: Property L{isnormal}, method L{normal} and function
1491
1492
  L{pygeodesy.normal}.
pygeodesy/lazily.py CHANGED
@@ -30,7 +30,7 @@ and line number.
30
30
  from pygeodesy import internals as _internals, interns as _interns, \
31
31
  _isfrozen # DON'T _lazy_import2
32
32
  # from pygeodesy.errors import _error_init # _ALL_MODS
33
- from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_main, \
33
+ from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_ismain, \
34
34
  _headof, _osversion2, printf, _Pythonarchine, \
35
35
  _tailof
36
36
  from pygeodesy.interns import NN, _areaOf_, _attribute_, _by_, _COLONSPACE_, \
@@ -269,7 +269,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
269
269
  'antipode', 'antipode_', 'bearing', 'bearing_',
270
270
  'compassAngle', 'cosineForsytheAndoyerLambert', 'cosineForsytheAndoyerLambert_',
271
271
  'cosineAndoyerLambert', 'cosineAndoyerLambert_', 'cosineLaw', 'cosineLaw_',
272
- 'equirectangular', 'equirectangular_', 'euclidean', 'euclidean_',
272
+ 'equirectangular', 'equirectangular4', 'euclidean', 'euclidean_',
273
273
  'excessAbc_', 'excessCagnoli_', 'excessGirard_', 'excessLHuilier_',
274
274
  'excessKarney', 'excessKarney_', 'excessQuad', 'excessQuad_',
275
275
  'flatLocal', 'flatLocal_', 'flatPolar', 'flatPolar_',
@@ -421,7 +421,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
421
421
  'R_M', 'R_MA', 'R_MB', 'R_KM', 'R_NM', 'R_SM', 'R_FM', 'R_VM'),
422
422
  deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ...
423
423
  'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ... ellipsoidal, spherical flavors
424
- 'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular3',
424
+ 'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular_', 'equirectangular3',
425
425
  'excessAbc', 'excessGirard', 'excessLHuilier',
426
426
  'false2f', 'falsed2f', 'float0', 'fStr', 'fStrzs', 'hypot3',
427
427
  'inStr', 'isenclosedby', 'istuplist',
@@ -771,7 +771,7 @@ def _lazy_init2(pack):
771
771
  _unLazy0 = _unlazy or not isLazy # pre-3.7 or w/o lazy import
772
772
 
773
773
  if isLazy < 1: # not enabled
774
- raise LazyImportError(_PYGEODESY_LAZY_IMPORT_, repr(z), txt=_not_(_enabled_))
774
+ raise LazyImportError(_PYGEODESY_LAZY_IMPORT_, repr(z), txt_not_=_enabled_)
775
775
  if _getenv('PYTHONVERBOSE', None): # PYCHOK no cover
776
776
  isLazy += 1
777
777
 
@@ -805,7 +805,7 @@ def _lazy_module(name): # overwritten by _lazy_import2
805
805
  # update the package's C{__dict__} accordingly.
806
806
  # '''
807
807
  # sm = dict()
808
- # if force and not _dunder_main(_dunder_name_):
808
+ # if force and not _dunder_ismain(_dunder_name_):
809
809
  # nm = _tailof(_dunder_name_)
810
810
  # _a = _ALL_MODS.getattr
811
811
  # _m = _ALL_MODS.getmodule
@@ -827,7 +827,7 @@ def _lazy_module(name): # overwritten by _lazy_import2
827
827
 
828
828
  # del _i, _i0
829
829
 
830
- if _dunder_main(__name__): # PYCHOK no cover
830
+ if _dunder_ismain(__name__): # PYCHOK no cover
831
831
 
832
832
  from timeit import timeit
833
833