pygeodesy 24.5.24__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 (57) hide show
  1. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
  2. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/RECORD +57 -57
  3. pygeodesy/__init__.py +4 -4
  4. pygeodesy/auxilats/__init__.py +1 -1
  5. pygeodesy/auxilats/__main__.py +2 -2
  6. pygeodesy/auxilats/auxAngle.py +4 -4
  7. pygeodesy/basics.py +39 -5
  8. pygeodesy/booleans.py +3 -3
  9. pygeodesy/constants.py +3 -3
  10. pygeodesy/deprecated/functions.py +9 -3
  11. pygeodesy/ecef.py +22 -21
  12. pygeodesy/ellipsoidalBase.py +15 -16
  13. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  14. pygeodesy/ellipsoidalKarney.py +3 -3
  15. pygeodesy/ellipsoids.py +6 -5
  16. pygeodesy/errors.py +19 -9
  17. pygeodesy/etm.py +16 -21
  18. pygeodesy/fmath.py +9 -20
  19. pygeodesy/formy.py +60 -74
  20. pygeodesy/frechet.py +11 -11
  21. pygeodesy/fsums.py +59 -25
  22. pygeodesy/geodesicx/__init__.py +1 -1
  23. pygeodesy/geodesicx/__main__.py +2 -2
  24. pygeodesy/geodesicx/gx.py +3 -5
  25. pygeodesy/geodsolve.py +2 -2
  26. pygeodesy/geohash.py +14 -14
  27. pygeodesy/hausdorff.py +12 -12
  28. pygeodesy/heights.py +5 -5
  29. pygeodesy/internals.py +3 -3
  30. pygeodesy/karney.py +8 -7
  31. pygeodesy/lazily.py +2 -2
  32. pygeodesy/ltp.py +62 -44
  33. pygeodesy/ltpTuples.py +202 -147
  34. pygeodesy/mgrs.py +24 -24
  35. pygeodesy/named.py +68 -70
  36. pygeodesy/nvectorBase.py +2 -2
  37. pygeodesy/osgr.py +40 -48
  38. pygeodesy/points.py +10 -10
  39. pygeodesy/props.py +29 -16
  40. pygeodesy/rhumb/aux_.py +13 -15
  41. pygeodesy/rhumb/bases.py +12 -5
  42. pygeodesy/rhumb/ekx.py +24 -18
  43. pygeodesy/rhumb/solve.py +13 -10
  44. pygeodesy/simplify.py +16 -16
  45. pygeodesy/solveBase.py +14 -14
  46. pygeodesy/sphericalBase.py +17 -21
  47. pygeodesy/sphericalTrigonometry.py +17 -17
  48. pygeodesy/trf.py +9 -7
  49. pygeodesy/triaxials.py +2 -2
  50. pygeodesy/ups.py +66 -70
  51. pygeodesy/utily.py +3 -3
  52. pygeodesy/utm.py +152 -156
  53. pygeodesy/utmups.py +38 -38
  54. pygeodesy/utmupsBase.py +102 -106
  55. pygeodesy/webmercator.py +43 -51
  56. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
  57. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/utmupsBase.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  u'''(INTERNAL) Private class C{UtmUpsBase}, functions and constants
5
- for L{epsg}, L{etm}, L{mgrs}, L{ups} and L{utm}.
5
+ for modules L{epsg}, L{etm}, L{mgrs}, L{ups} and L{utm}.
6
6
  '''
7
7
 
8
8
  from pygeodesy.basics import isint, isscalar, isstr, neg_, \
@@ -11,12 +11,12 @@ from pygeodesy.constants import _float, _0_0, _0_5, _N_90_0, _180_0
11
11
  from pygeodesy.datums import _ellipsoidal_datum, _WGS84
12
12
  from pygeodesy.dms import degDMS, parseDMS2
13
13
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
14
- from pygeodesy.errors import _or, ParseError, _parseX, _UnexpectedError, \
15
- _ValueError, _xkwds, _xkwds_not, _xkwds_pop2
14
+ from pygeodesy.errors import _or, ParseError, _parseX, _ValueError, \
15
+ _xkwds, _xkwds_not
16
16
  # from pygeodesy.internals import _name__, _under # from .named
17
17
  from pygeodesy.interns import NN, _A_, _B_, _COMMA_, _Error_, \
18
18
  _gamma_, _n_a_, _not_, _N_, _NS_, _PLUS_, \
19
- _scale_, _SPACE_, _Y_, _Z_
19
+ _S_, _scale_, _SPACE_, _Y_, _Z_
20
20
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
21
21
  from pygeodesy.named import _NamedBase, _xnamed, _name__, _under
22
22
  from pygeodesy.namedTuples import EasNor2Tuple, LatLonDatum5Tuple
@@ -27,7 +27,7 @@ from pygeodesy.units import Band, Easting, Northing, Scalar, Zone
27
27
  from pygeodesy.utily import _Wrap, wrap360
28
28
 
29
29
  __all__ = _ALL_LAZY.utmupsBase
30
- __version__ = '24.05.19'
30
+ __version__ = '24.05.30'
31
31
 
32
32
  _UPS_BANDS = _A_, _B_, _Y_, _Z_ # UPS polar bands SE, SW, NE, NW
33
33
  # _UTM_BANDS = _MODS.utm._Bands
@@ -59,94 +59,6 @@ _UTMUPS_ZONE_MIN = _UPS_ZONE # PYCHOK for export too, by .units.py
59
59
  # _UTM = -2
60
60
 
61
61
 
62
- def _hemi(lat, N=0): # imported by .ups, .utm
63
- '''Return the hemisphere letter.
64
-
65
- @arg lat: Latitude (C{degrees} or C{radians}).
66
- @kwarg N: Minimal North latitude, C{0} or C{_N_}.
67
-
68
- @return: C{'N'|'S'} for north-/southern hemisphere.
69
- '''
70
- return _NS_[int(lat < N)]
71
-
72
-
73
- def _to4lldn(latlon, lon, datum, name, wrap=False):
74
- '''(INTERNAL) Return 4-tuple (C{lat, lon, datum, name}).
75
- '''
76
- try:
77
- # if lon is not None:
78
- # raise AttributeError
79
- lat, lon = float(latlon.lat), float(latlon.lon)
80
- _xinstanceof(_LLEB, LatLonDatum5Tuple, latlon=latlon)
81
- if wrap:
82
- _Wrap.latlon(lat, lon)
83
- d = datum or latlon.datum
84
- except AttributeError:
85
- lat, lon = _Wrap.latlonDMS2(latlon, lon) if wrap else \
86
- parseDMS2(latlon, lon) # clipped
87
- d = datum or _WGS84
88
- return lat, lon, d, _name__(name, _or_nameof=latlon)
89
-
90
-
91
- def _to3zBhp(zone, band, hemipole=NN, Error=_ValueError): # imported by .epsg, .ups, .utm, .utmups
92
- '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter.
93
-
94
- @arg zone: Zone with/-out Band (C{scalar} or C{str}).
95
- @kwarg band: Optional I{longitudinal/polar} Band letter (C{str}).
96
- @kwarg hemipole: Optional hemisphere/pole letter (C{str}).
97
- @kwarg Error: Optional error to raise, overriding the default
98
- C{ValueError}.
99
-
100
- @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int, str,
101
- 'N'|'S'}) where C{zone} is C{0} for UPS or C{1..60} for
102
- UTM and C{Band} is C{'A'..'Z'} I{NOT} checked for valid
103
- UTM/UPS bands.
104
-
105
- @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}.
106
- '''
107
- try:
108
- B, z = band, _UTMUPS_ZONE_INVALID
109
- if isscalar(zone):
110
- z = int(zone)
111
- elif zone and isstr(zone):
112
- if zone.isdigit():
113
- z = int(zone)
114
- elif len(zone) > 1:
115
- B = zone[-1:]
116
- z = int(zone[:-1])
117
- elif zone.upper() in _UPS_BANDS: # single letter
118
- B = zone
119
- z = _UPS_ZONE
120
-
121
- if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX:
122
- hp = hemipole[:1].upper()
123
- if hp in _NS_ or not hp:
124
- z = Zone(z)
125
- B = Band(B.upper())
126
- if B.isalpha():
127
- return z, B, (hp or _hemi(B, _N_))
128
- elif not B:
129
- return z, B, hp
130
-
131
- raise ValueError # _invalid_
132
- except (AttributeError, IndexError, TypeError, ValueError) as x:
133
- raise Error(zone=zone, band=B, hemipole=hemipole, cause=x)
134
-
135
-
136
- def _to3zll(lat, lon): # imported by .ups, .utm
137
- '''Wrap lat- and longitude and determine UTM zone.
138
-
139
- @arg lat: Latitude (C{degrees}).
140
- @arg lon: Longitude (C{degrees}).
141
-
142
- @return: 3-Tuple (C{zone, lat, lon}) as (C{int}, C{degrees90},
143
- C{degrees180}) where C{zone} is C{1..60} for UTM.
144
- '''
145
- x = wrap360(lon + _180_0) # use wrap360 to get ...
146
- z = int(x) // 6 + 1 # ... longitudinal UTM zone [1, 60] and ...
147
- return Zone(z), lat, (x - _180_0) # ... -180 <= lon < 180
148
-
149
-
150
62
  class UtmUpsBase(_NamedBase):
151
63
  '''(INTERNAL) Base class for L{Utm} and L{Ups} coordinates.
152
64
  '''
@@ -166,7 +78,7 @@ class UtmUpsBase(_NamedBase):
166
78
  _utm = None # cached toUtm (L{Utm})
167
79
 
168
80
  def __init__(self, easting, northing, band=NN, datum=None, falsed=True,
169
- gamma=None, scale=None, **convergence):
81
+ gamma=None, scale=None):
170
82
  '''(INTERNAL) New L{UtmUpsBase}.
171
83
  '''
172
84
  E = self._Error
@@ -185,10 +97,6 @@ class UtmUpsBase(_NamedBase):
185
97
  if not falsed:
186
98
  self._falsed = False
187
99
 
188
- if convergence: # for backward compatibility
189
- gamma, kwds = _xkwds_pop2(convergence, convergence=gamma)
190
- if kwds:
191
- raise _UnexpectedError(**kwds)
192
100
  if gamma is not self._gamma:
193
101
  self._gamma = Scalar(gamma=gamma, Error=E)
194
102
  if scale is not self._scale:
@@ -272,7 +180,7 @@ class UtmUpsBase(_NamedBase):
272
180
 
273
181
  @Property_RO
274
182
  def falsed(self):
275
- '''Get easting and northing falsed (C{bool}).
183
+ '''Are easting and northing falsed (C{bool})?
276
184
  '''
277
185
  return self._falsed
278
186
 
@@ -310,9 +218,11 @@ class UtmUpsBase(_NamedBase):
310
218
  ll, _under(_gamma_), _under(_scale_))
311
219
  return _xnamed(r, ll.name)
312
220
 
313
- def _latlon5args(self, ll, _toBand, unfalse, *other):
221
+ def _latlon5args(self, ll, g, k, _toBand, unfalse, *other):
314
222
  '''(INTERNAL) See C{._toLLEB} methods, functions C{ups.toUps8} and C{utm._toXtm8}
315
223
  '''
224
+ ll._gamma = g
225
+ ll._scale = k
316
226
  ll._toLLEB_args = (unfalse,) + other
317
227
  if unfalse:
318
228
  if not self._band:
@@ -418,17 +328,26 @@ class UtmUpsBase(_NamedBase):
418
328
  return t if sep is None else sep.join(t)
419
329
 
420
330
 
421
- def _lowerleft(utmups, center): # by .ellipsoidalBase._lowerleft
331
+ def _hemi(lat, N=0): # in .ups, .utm
332
+ '''Return the hemisphere letter.
333
+
334
+ @arg lat: Latitude (C{degrees} or C{radians}).
335
+ @kwarg N: Minimal North latitude, C{0} or C{_N_}.
336
+
337
+ @return: C{'N'|'S'} for north-/southern hemisphere.
338
+ '''
339
+ return _S_ if lat < N else _N_
340
+
341
+
342
+ def _lowerleft(utmups, center): # in .ellipsoidalBase._lowerleft
422
343
  '''(INTERNAL) I{Un}-center a B{C{utmups}} to its C{lowerleft} by
423
344
  C{B{center} meter} or by a I{guess} if B{C{center}} is C{0}.
424
345
  '''
425
346
  if center:
426
347
  e = n = -center
427
348
  else:
428
- c = 5 # center
429
- for _ in range(3):
430
- c *= 10 # 50, 500, 5000
431
- t = c * 2
349
+ for c in (50, 500, 5000):
350
+ t = c * 2
432
351
  e = int(utmups.easting % t)
433
352
  n = int(utmups.northing % t)
434
353
  if (e == c and n in (c, c - 1)) or \
@@ -439,7 +358,7 @@ def _lowerleft(utmups, center): # by .ellipsoidalBase._lowerleft
439
358
 
440
359
  r = _xkwds_not(None, datum=utmups.datum,
441
360
  gamma=utmups.gamma,
442
- scale=utmups.scale)
361
+ scale=utmups.scale, name=utmups.name)
443
362
  return utmups.classof(utmups.zone, utmups.hemisphere,
444
363
  utmups.easting - e, utmups.northing - n,
445
364
  band=utmups.band, falsed=utmups.falsed, **r)
@@ -489,12 +408,89 @@ def _parseUTMUPS5(strUTMUPS, UPS, Error=ParseError, band=NN, sep=_COMMA_):
489
408
  strUTMUPS=strUTMUPS, Error=Error)
490
409
 
491
410
 
411
+ def _to4lldn(latlon, lon, datum, name, wrap=False):
412
+ '''(INTERNAL) Return 4-tuple (C{lat, lon, datum, name}).
413
+ '''
414
+ try:
415
+ # if lon is not None:
416
+ # raise AttributeError
417
+ lat, lon = float(latlon.lat), float(latlon.lon)
418
+ _xinstanceof(_LLEB, LatLonDatum5Tuple, latlon=latlon)
419
+ if wrap:
420
+ _Wrap.latlon(lat, lon)
421
+ d = datum or latlon.datum
422
+ except AttributeError: # TypeError
423
+ lat, lon = _Wrap.latlonDMS2(latlon, lon) if wrap else \
424
+ parseDMS2(latlon, lon) # clipped
425
+ d = datum or _WGS84
426
+ return lat, lon, d, _name__(name, _or_nameof=latlon)
427
+
428
+
492
429
  def _toMgrs(utmups):
493
430
  '''(INTERNAL) Convert a L{Utm} or L{Ups} to an L{Mgrs} instance.
494
431
  '''
495
432
  return _MODS.mgrs.toMgrs(utmups, datum=utmups.datum, name=utmups.name)
496
433
 
497
434
 
435
+ def _to3zBhp(zone, band, hemipole=NN, Error=_ValueError): # in .epsg, .ups, .utm, .utmups
436
+ '''Parse UTM/UPS zone, Band letter and hemisphere/pole letter.
437
+
438
+ @arg zone: Zone with/-out Band (C{scalar} or C{str}).
439
+ @kwarg band: Optional I{longitudinal/polar} Band letter (C{str}).
440
+ @kwarg hemipole: Optional hemisphere/pole letter (C{str}).
441
+ @kwarg Error: Optional error to raise, overriding the default
442
+ C{ValueError}.
443
+
444
+ @return: 3-Tuple (C{zone, Band, hemisphere/pole}) as (C{int, str,
445
+ 'N'|'S'}) where C{zone} is C{0} for UPS or C{1..60} for
446
+ UTM and C{Band} is C{'A'..'Z'} I{NOT} checked for valid
447
+ UTM/UPS bands.
448
+
449
+ @raise ValueError: Invalid B{C{zone}}, B{C{band}} or B{C{hemipole}}.
450
+ '''
451
+ try:
452
+ B, z = band, _UTMUPS_ZONE_INVALID
453
+ if isscalar(zone):
454
+ z = int(zone)
455
+ elif zone and isstr(zone):
456
+ if zone.isdigit():
457
+ z = int(zone)
458
+ elif len(zone) > 1:
459
+ B = zone[-1:]
460
+ z = int(zone[:-1])
461
+ elif zone.upper() in _UPS_BANDS: # single letter
462
+ B = zone
463
+ z = _UPS_ZONE
464
+
465
+ if _UTMUPS_ZONE_MIN <= z <= _UTMUPS_ZONE_MAX:
466
+ hp = hemipole[:1].upper()
467
+ if hp in _NS_ or not hp:
468
+ z = Zone(z)
469
+ B = Band(B.upper())
470
+ if B.isalpha():
471
+ return z, B, (hp or _hemi(B, _N_))
472
+ elif not B:
473
+ return z, B, hp
474
+
475
+ raise ValueError # _invalid_
476
+ except (AttributeError, IndexError, TypeError, ValueError) as x:
477
+ raise Error(zone=zone, band=B, hemipole=hemipole, cause=x)
478
+
479
+
480
+ def _to3zll(lat, lon): # in .ups, .utm
481
+ '''Wrap lat- and longitude and determine UTM zone.
482
+
483
+ @arg lat: Latitude (C{degrees}).
484
+ @arg lon: Longitude (C{degrees}).
485
+
486
+ @return: 3-Tuple (C{zone, lat, lon}) as (C{int}, C{degrees90},
487
+ C{degrees180}) where C{zone} is C{1..60} for UTM.
488
+ '''
489
+ x = wrap360(lon + _180_0) # use wrap360 to get ...
490
+ z = int(x) // 6 + 1 # ... longitudinal UTM zone [1, 60] and ...
491
+ return Zone(z), lat, (x - _180_0) # ... -180 <= lon < 180
492
+
493
+
498
494
  __all__ += _ALL_DOCS(UtmUpsBase)
499
495
 
500
496
  # **) MIT License
pygeodesy/webmercator.py CHANGED
@@ -22,11 +22,11 @@ from pygeodesy.basics import _splituple, _xinstanceof
22
22
  from pygeodesy.constants import PI_2, R_MA, _2_0
23
23
  from pygeodesy.datums import Datum, _spherical_datum
24
24
  from pygeodesy.dms import clipDegrees, parseDMS2
25
- from pygeodesy.errors import _parseX, _ValueError, _xattr, _xkwds
25
+ from pygeodesy.errors import _parseX, _ValueError, _xattr, _xkwds, _xkwds_pop2
26
26
  from pygeodesy.interns import NN, _COMMASPACE_, _datum_, _earth_, _easting_, \
27
27
  _northing_, _radius_, _SPACE_, _x_, _y_
28
28
  # from pygeodesy.lazily import _ALL_LAZY from .named
29
- from pygeodesy.named import _NamedBase, _NamedTuple, _ALL_LAZY
29
+ from pygeodesy.named import _name2__, _NamedBase, _NamedTuple, _ALL_LAZY
30
30
  from pygeodesy.namedTuples import LatLon2Tuple, LatLonDatum3Tuple, PhiLam2Tuple
31
31
  from pygeodesy.props import deprecated_method, Property_RO
32
32
  from pygeodesy.streprs import Fmt, strs, _xzipairs
@@ -36,7 +36,7 @@ from pygeodesy.utily import degrees90, degrees180
36
36
  from math import atan, atanh, exp, radians, sin, tanh
37
37
 
38
38
  __all__ = _ALL_LAZY.webmercator
39
- __version__ = '24.02.04'
39
+ __version__ = '24.05.31'
40
40
 
41
41
  # _FalseEasting = 0 # false Easting (C{meter})
42
42
  # _FalseNorthing = 0 # false Northing (C{meter})
@@ -66,32 +66,30 @@ class Wm(_NamedBase):
66
66
  _x = 0 # Easting (C{meter})
67
67
  _y = 0 # Northing (C{meter})
68
68
 
69
- def __init__(self, x, y, earth=R_MA, name=NN, **radius):
69
+ def __init__(self, x, y, earth=R_MA, **name_radius):
70
70
  '''New L{Wm} Web Mercator (WM) coordinate.
71
71
 
72
72
  @arg x: Easting from central meridian (C{meter}).
73
73
  @arg y: Northing from equator (C{meter}).
74
- @kwarg earth: Earth radius (C{meter}), datum or
75
- ellipsoid (L{Datum}, L{a_f2Tuple},
76
- L{Ellipsoid} or L{Ellipsoid2}).
77
- @kwarg name: Optional name (C{str}).
78
- @kwarg radius: DEPRECATED, use keyword argument B{C{earth}}.
74
+ @kwarg earth: Earth radius (C{meter}), datum or ellipsoid (L{Datum},
75
+ L{a_f2Tuple}, L{Ellipsoid} or L{Ellipsoid2}).
76
+ @kwarg name_radius: Optional C{B{name}=NN} (C{str}) and DEPRECATED
77
+ keyword argument C{B{radius}=earth}, use B{C{earth}}.
79
78
 
80
- @note: WM is strictly defined for spherical and WGS84
81
- ellipsoidal earth models only.
79
+ @note: WM is strictly defined for spherical and WGS84 ellipsoidal
80
+ earth models only.
82
81
 
83
82
  @raise WebMercatorError: Invalid B{C{x}}, B{C{y}} or B{C{radius}}.
84
83
  '''
85
84
  self._x = Easting( x=x, Error=WebMercatorError)
86
85
  self._y = Northing(y=y, Error=WebMercatorError)
87
86
 
88
- R = radius.get(_radius_, earth)
89
- if R not in Wm._earths:
90
- self._datum = _datum(R, _radius_ if radius else _earth_)
91
- self._radius = self.datum.ellipsoid.a
92
-
87
+ R, name = _xkwds_pop2(name_radius, radius=earth)
93
88
  if name:
94
89
  self.name = name
90
+ if R not in Wm._earths:
91
+ self._datum = _datum(R, _radius_ if _radius_ in name_radius else _earth_)
92
+ self._radius = self.datum.ellipsoid.a
95
93
 
96
94
  @Property_RO
97
95
  def datum(self):
@@ -143,20 +141,18 @@ class Wm(_NamedBase):
143
141
 
144
142
  return LatLon2Tuple(degrees90(y), degrees180(x), name=self.name)
145
143
 
146
- def parse(self, strWM, name=NN):
144
+ def parse(self, strWM, **name):
147
145
  '''Parse a string to a similar L{Wm} instance.
148
146
 
149
- @arg strWM: The WM coordinate (C{str}), see
150
- function L{parseWM}.
151
- @kwarg name: Optional instance name (C{str}),
152
- overriding this name.
147
+ @arg strWM: The WM coordinate (C{str}), see function L{parseWM}.
148
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
153
149
 
154
150
  @return: The similar instance (L{Wm}).
155
151
 
156
152
  @raise WebMercatorError: Invalid B{C{strWM}}.
157
153
  '''
158
154
  return parseWM(strWM, radius=self.radius, Wm=self.classof,
159
- name=name or self.name)
155
+ name=self._name__(name))
160
156
 
161
157
  @deprecated_method
162
158
  def parseWM(self, strWM, name=NN): # PYCHOK no cover
@@ -189,16 +185,14 @@ class Wm(_NamedBase):
189
185
  @kwarg LatLon: Ellipsoidal or sphperical C{LatLon} class to
190
186
  return the geodetic point (C{LatLon}) or C{None}.
191
187
  @kwarg datum: Optional, datum (C{Datum}) overriding this WM's.
192
- @kwarg LatLon_kwds: Optional, additional B{C{LatLon}}
193
- keyword arguments, ignored if
194
- C{B{LatLon} is None}.
188
+ @kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
189
+ arguments, ignored if C{B{LatLon} is None}.
195
190
 
196
- @return: This WM coordinate as B{C{LatLon}} or if
197
- C{B{LatLon} is None} a L{LatLonDatum3Tuple}.
191
+ @return: This WM coordinate as B{C{LatLon}} or if C{B{LatLon}
192
+ is None} a L{LatLonDatum3Tuple}.
198
193
 
199
- @raise TypeError: If B{C{LatLon}} and B{C{datum}} are
200
- incompatible or if B{C{datum}} is
201
- invalid.
194
+ @raise TypeError: If B{C{datum}} is invalid or if B{C{LatLon}}
195
+ and B{C{datum}} are incompatible.
202
196
  '''
203
197
  d = datum or self.datum
204
198
  _xinstanceof(Datum, datum=d)
@@ -278,7 +272,7 @@ def _datum(earth, name=_datum_):
278
272
  raise WebMercatorError(name, earth, cause=x)
279
273
 
280
274
 
281
- def parseWM(strWM, radius=R_MA, Wm=Wm, name=NN):
275
+ def parseWM(strWM, radius=R_MA, Wm=Wm, **name):
282
276
  '''Parse a string C{"e n [r]"} representing a WM coordinate,
283
277
  consisting of easting, northing and an optional radius.
284
278
 
@@ -287,11 +281,10 @@ def parseWM(strWM, radius=R_MA, Wm=Wm, name=NN):
287
281
  case B{C{strWM}} doesn't include C{r}.
288
282
  @kwarg Wm: Optional class to return the WM coordinate (L{Wm})
289
283
  or C{None}.
290
- @kwarg name: Optional name (C{str}).
284
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
291
285
 
292
- @return: The WM coordinate (B{C{Wm}}) or an
293
- L{EasNorRadius3Tuple}C{(easting, northing, radius)}
294
- if B{C{Wm}} is C{None}.
286
+ @return: The WM coordinate (B{C{Wm}}) or if B{C{Wm}} is C{None}
287
+ an L{EasNorRadius3Tuple}C{(easting, northing, radius)}.
295
288
 
296
289
  @raise WebMercatorError: Invalid B{C{strWM}}.
297
290
  '''
@@ -304,14 +297,14 @@ def parseWM(strWM, radius=R_MA, Wm=Wm, name=NN):
304
297
  raise ValueError
305
298
  x, y, R = map(float, w)
306
299
 
307
- return EasNorRadius3Tuple(x, y, R, name=name) if Wm is None else \
308
- Wm(x, y, earth=R, name=name)
300
+ return EasNorRadius3Tuple(x, y, R, **name) if Wm is None else \
301
+ Wm(x, y, earth=R, **name)
309
302
 
310
303
  return _parseX(_WM, strWM, radius, Wm, name,
311
304
  strWM=strWM, Error=WebMercatorError)
312
305
 
313
306
 
314
- def toWm(latlon, lon=None, earth=R_MA, Wm=Wm, name=NN, **Wm_kwds):
307
+ def toWm(latlon, lon=None, earth=R_MA, Wm=Wm, **name_Wm_kwds_radius):
315
308
  '''Convert a lat-/longitude point to a WM coordinate.
316
309
 
317
310
  @arg latlon: Latitude (C{degrees}) or an (ellipsoidal or
@@ -323,31 +316,30 @@ def toWm(latlon, lon=None, earth=R_MA, Wm=Wm, name=NN, **Wm_kwds):
323
316
  datum if present.
324
317
  @kwarg Wm: Optional class to return the WM coordinate (L{Wm})
325
318
  or C{None}.
326
- @kwarg name: Optional name (C{str}).
327
- @kwarg Wm_kwds: Optional, additional B{C{Wm}} keyword arguments,
328
- ignored if C{B{Wm} is None}.
319
+ @kwarg name_Wm_kwds_radius: Optional C{B{name}=NN} (C{str}),
320
+ optional, additional B{C{Wm}} keyword arguments,
321
+ ignored if C{B{Wm} is None} and DEPRECATED keyword
322
+ argument C{B{radius}=earth}, use B{C{earth}}.
329
323
 
330
- @return: The WM coordinate (B{C{Wm}}) or if B{C{Wm}} is C{None}
331
- an L{EasNorRadius3Tuple}C{(easting, northing, radius)}.
324
+ @return: The WM coordinate (B{C{Wm}}) or if B{C{Wm}} is C{None} an
325
+ L{EasNorRadius3Tuple}C{(easting, northing, radius)}.
332
326
 
333
327
  @raise ValueError: If B{C{lon}} value is missing, if B{C{latlon}} is not
334
328
  scalar, if B{C{latlon}} is beyond the valid WM range
335
329
  and L{pygeodesy.rangerrors} is set to C{True} or if
336
330
  B{C{earth}} is invalid.
337
331
  '''
338
- if _radius_ in Wm_kwds: # remove DEPRECATED, radius
339
- d = _datum(Wm_kwds.pop(_radius_), _radius_)
340
- else:
341
- d = _datum(earth, _earth_)
332
+ name, kwds = _name2__(name_Wm_kwds_radius)
333
+ R, kwds = _xkwds_pop2(kwds, radius=earth)
334
+ d = _datum(R, _radius_ if _radius_ in name_Wm_kwds_radius else _earth_)
342
335
  try:
343
336
  y, x = latlon.lat, latlon.lon
344
337
  y = clipDegrees(y, _LatLimit)
345
338
  d = _xattr(latlon, datum=d)
346
- n = name or _xattr(latlon, name=NN)
339
+ n = latlon._name__(name)
347
340
  except AttributeError:
348
341
  y, x = parseDMS2(latlon, lon, clipLat=_LatLimit)
349
- n = name
350
-
342
+ n = name
351
343
  E = d.ellipsoid
352
344
  R = E.a
353
345
  s = sin(radians(y))
@@ -357,7 +349,7 @@ def toWm(latlon, lon=None, earth=R_MA, Wm=Wm, name=NN, **Wm_kwds):
357
349
  y *= R
358
350
  x = R * radians(x)
359
351
  r = EasNorRadius3Tuple(x, y, R, name=n) if Wm is None else \
360
- Wm(x, y, **_xkwds(Wm_kwds, earth=d, name=n))
352
+ Wm(x, y, **_xkwds(kwds, earth=d, name=n))
361
353
  return r
362
354
 
363
355
  # **) MIT License