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/mgrs.py CHANGED
@@ -44,7 +44,7 @@ from pygeodesy.interns import NN, _0_, _A_, _AtoZnoIO_, _band_, _B_, \
44
44
  _COMMASPACE_, _datum_, _easting_, _invalid_, \
45
45
  _northing_, _SPACE_, _W_, _Y_, _Z_, _zone_
46
46
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _PYGEODESY_GEOCONVERT_
47
- from pygeodesy.named import _NamedBase, _NamedTuple, _Pass, _xnamed
47
+ from pygeodesy.named import _name2__, _NamedBase, _NamedTuple, _Pass
48
48
  from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple
49
49
  from pygeodesy.props import deprecated_property_RO, property_RO, Property_RO
50
50
  from pygeodesy.streprs import enstr2, _enstr2m3, Fmt, _resolution10, _xzipairs
@@ -55,7 +55,7 @@ from pygeodesy.utm import toUtm8, _to3zBlat, Utm, _UTM_ZONE_MAX, _UTM_ZONE_MIN
55
55
  # from pygeodesy.utmupsBase import _UTM_ZONE_MAX, _UTM_ZONE_MIN # from .utm
56
56
 
57
57
  __all__ = _ALL_LAZY.mgrs
58
- __version__ = '24.05.24'
58
+ __version__ = '24.05.31'
59
59
 
60
60
  _AN_ = 'AN' # default south pole grid tile and band B
61
61
  _AtoPx_ = _AtoZnoIO_.tillP
@@ -87,7 +87,7 @@ class Mgrs(_NamedBase):
87
87
  _zone = 0 # longitudinal or polar zone (C{int}), 0..60
88
88
 
89
89
  def __init__(self, zone=0, EN=NN, easting=0, northing=0, band=NN,
90
- datum=_WGS84, resolution=0, name=NN):
90
+ datum=_WGS84, resolution=0, **name):
91
91
  '''New L{Mgrs} Military grid reference.
92
92
 
93
93
  @arg zone: The 6° I{longitudinal} zone (C{int}), 1..60 covering
@@ -104,7 +104,7 @@ class Mgrs(_NamedBase):
104
104
  @kwarg datum: This reference's datum (L{Datum}, L{Ellipsoid},
105
105
  L{Ellipsoid2} or L{a_f2Tuple}).
106
106
  @kwarg resolution: Optional resolution (C{meter}), C{0} for default.
107
- @kwarg name: Optional name (C{str}).
107
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
108
108
 
109
109
  @raise MGRSError: Invalid B{C{zone}}, B{C{EN}}, B{C{easting}},
110
110
  B{C{northing}}, B{C{band}} or B{C{resolution}}.
@@ -235,20 +235,18 @@ class Mgrs(_NamedBase):
235
235
  toUps8(a, 0, datum=self.datum, Ups=None)
236
236
  return int(u.northing / _100km) * _100km
237
237
 
238
- def parse(self, strMGRS, name=NN):
238
+ def parse(self, strMGRS, **name):
239
239
  '''Parse a string to a similar L{Mgrs} instance.
240
240
 
241
- @arg strMGRS: The MGRS reference (C{str}),
242
- see function L{parseMGRS}.
243
- @kwarg name: Optional instance name (C{str}),
244
- overriding this name.
241
+ @arg strMGRS: The MGRS reference (C{str}), see function L{parseMGRS}.
242
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
245
243
 
246
244
  @return: The similar instance (L{Mgrs}).
247
245
 
248
246
  @raise MGRSError: Invalid B{C{strMGRS}}.
249
247
  '''
250
248
  return parseMGRS(strMGRS, datum=self.datum, Mgrs=self.classof,
251
- name=name or self.name)
249
+ name=self._name__(name))
252
250
 
253
251
  @property
254
252
  def resolution(self):
@@ -536,7 +534,7 @@ class _RE(object):
536
534
  _RE = _RE() # PYCHOK singleton
537
535
 
538
536
 
539
- def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name=NN):
537
+ def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, **name):
540
538
  '''Parse a string representing a MGRS grid reference,
541
539
  consisting of C{"[zone]Band, EN, easting, northing"}.
542
540
 
@@ -544,7 +542,7 @@ def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name=NN):
544
542
  @kwarg datum: Optional datum to use (L{Datum}).
545
543
  @kwarg Mgrs: Optional class to return the MGRS grid
546
544
  reference (L{Mgrs}) or C{None}.
547
- @kwarg name: Optional B{C{Mgrs}} name (C{str}).
545
+ @kwarg name: Optional B{C{Mgrs}} C{B{name}=NN} (C{str}).
548
546
 
549
547
  @return: The MGRS grid reference as B{C{Mgrs}} or if
550
548
  C{B{Mgrs} is None} as an L{Mgrs4Tuple}C{(zone,
@@ -582,29 +580,29 @@ def parseMGRS(strMGRS, datum=_WGS84, Mgrs=Mgrs, name=NN):
582
580
  e, n, m = _enstr2m3(*m[2:])
583
581
 
584
582
  if Mgrs is None:
585
- r = Mgrs4Tuple(zB, EN, e, n, name=name)
583
+ r = Mgrs4Tuple(zB, EN, e, n, **name)
586
584
  _ = r.toMgrs(resolution=m) # validate
587
585
  else:
588
- r = Mgrs(zB, EN, e, n, datum=datum, resolution=m, name=name)
586
+ r = Mgrs(zB, EN, e, n, datum=datum, resolution=m, **name)
589
587
  return r
590
588
 
591
589
  return _parseX(_MGRS, strMGRS, datum, Mgrs, name,
592
590
  strMGRS=strMGRS, Error=MGRSError)
593
591
 
594
592
 
595
- def toMgrs(utmups, Mgrs=Mgrs, name=NN, **Mgrs_kwds):
593
+ def toMgrs(utmups, Mgrs=Mgrs, **name_Mgrs_kwds):
596
594
  '''Convert a UTM or UPS coordinate to an MGRS grid reference.
597
595
 
598
596
  @arg utmups: A UTM or UPS coordinate (L{Utm}, L{Etm} or L{Ups}).
599
597
  @kwarg Mgrs: Optional class to return the MGRS grid reference
600
598
  (L{Mgrs}) or C{None}.
601
- @kwarg name: Optional B{C{Mgrs}} name (C{str}).
602
- @kwarg Mgrs_kwds: Optional, additional B{C{Mgrs}} keyword
603
- arguments, ignored if C{B{Mgrs} is None}.
599
+ @kwarg name_Mgrs_kwds: Optional C{B{name}=NN} (C{str}) and
600
+ optional, additional B{C{Mgrs}} keyword arguments,
601
+ ignored if C{B{Mgrs} is None}.
604
602
 
605
- @return: The MGRS grid reference as B{C{Mgrs}} or if
606
- C{B{Mgrs} is None} as an L{Mgrs6Tuple}C{(zone,
607
- EN, easting, northing, band, datum)}.
603
+ @return: The MGRS grid reference as B{C{Mgrs}} or if C{B{Mgrs}
604
+ is None} as an L{Mgrs6Tuple}C{(zone, EN, easting,
605
+ northing, band, datum)}.
608
606
 
609
607
  @raise MGRSError: Invalid B{C{utmups}}.
610
608
 
@@ -634,12 +632,14 @@ def toMgrs(utmups, Mgrs=Mgrs, name=NN, **Mgrs_kwds):
634
632
  except (IndexError, TypeError, ValueError) as x:
635
633
  raise MGRSError(B=B, E=E, N=N, utmups=utmups, cause=x)
636
634
 
635
+ t, kwds = _name2__(name_Mgrs_kwds, _or_nameof=utmups)
637
636
  if Mgrs is None:
638
- r = Mgrs4Tuple(Fmt.zone(z), EN, e, n).to6Tuple(B, utmups.datum)
637
+ r = Mgrs4Tuple(Fmt.zone(z), EN, e, n, name=t) \
638
+ .to6Tuple(B, utmups.datum)
639
639
  else:
640
- kwds = _xkwds(Mgrs_kwds, band=B, datum=utmups.datum)
640
+ kwds = _xkwds(kwds, band=B, datum=utmups.datum, name=t)
641
641
  r = Mgrs(z, EN, e, n, **kwds)
642
- return _xnamed(r, name or utmups.name)
642
+ return r
643
643
 
644
644
 
645
645
  def _um100km2(m):
pygeodesy/named.py CHANGED
@@ -33,7 +33,7 @@ from pygeodesy.props import _allPropertiesOf_n, deprecated_method, _hasProperty,
33
33
  from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
34
34
 
35
35
  __all__ = _ALL_LAZY.named
36
- __version__ = '24.05.21'
36
+ __version__ = '24.05.31'
37
37
 
38
38
  _COMMANL_ = _COMMA_ + _NL_
39
39
  _COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
@@ -50,69 +50,6 @@ _Units_ = '_Units_'
50
50
  _UP = 2
51
51
 
52
52
 
53
- def _xjoined_(prefix, name=NN, enquote=True, **name__of_name):
54
- '''(INTERNAL) Join C{prefix} and non-empty C{name}.
55
- '''
56
- if name__of_name:
57
- name = _name__(name, **name__of_name)
58
- if name and prefix:
59
- if enquote:
60
- name = repr(name)
61
- t = _SPACE_(prefix, name)
62
- else:
63
- t = prefix or name
64
- return t
65
-
66
-
67
- def _xnamed(inst, name=NN, force=False, **name__of_name):
68
- '''(INTERNAL) Set the instance' C{.name = B{name}}.
69
-
70
- @arg inst: The instance (C{_Named}).
71
- @kwarg name: The name (C{str}).
72
- @kwarg force: If C{True}, force rename (C{bool}).
73
-
74
- @return: The B{C{inst}}, renamed if B{C{force}}d
75
- or if not named before.
76
- '''
77
- if name__of_name:
78
- name = _name__(name, **name__of_name)
79
- if name and isinstance(inst, _Named):
80
- if not inst.name:
81
- inst.name = name
82
- elif force:
83
- inst.rename(name)
84
- return inst
85
-
86
-
87
- def _xother3(inst, other, name=_other_, up=1, **name_other):
88
- '''(INTERNAL) Get C{name} and C{up} for a named C{other}.
89
- '''
90
- if name_other: # and other is None
91
- name, other = _xkwds_item2(name_other)
92
- elif other and len(other) == 1:
93
- name, other = _name__(name), other[0]
94
- else:
95
- raise _AssertionError(name, other, txt=classname(inst, prefixed=True))
96
- return other, name, up
97
-
98
-
99
- def _xotherError(inst, other, name=_other_, up=1):
100
- '''(INTERNAL) Return a C{_TypeError} for an incompatible, named C{other}.
101
- '''
102
- n = _callname(name, classname(inst, prefixed=True), inst.name, up=up + 1)
103
- return _TypeError(name, other, txt=_incompatible(n))
104
-
105
-
106
- def _xvalid(name, underOK=False):
107
- '''(INTERNAL) Check valid attribute name C{name}.
108
- '''
109
- return bool(name and isstr(name)
110
- and name != _name_
111
- and (underOK or not name.startswith(_UNDER_))
112
- and (not iskeyword(name))
113
- and isidentifier(name))
114
-
115
-
116
53
  class ADict(dict):
117
54
  '''A C{dict} with both key I{and} attribute access to
118
55
  the C{dict} items.
@@ -170,7 +107,6 @@ class ADict(dict):
170
107
  C{floats} formatted by function L{pygeodesy.fstr}.
171
108
  '''
172
109
  n = _xattr(self, name=NN) or self.__class__.__name__
173
- print(1, n)
174
110
  return Fmt.PAREN(n, self._toT(_EQUAL_, **prec_fmt))
175
111
 
176
112
  def toStr(self, **prec_fmt):
@@ -1300,13 +1236,12 @@ def _name__(name=NN, **kwds):
1300
1236
  return name if name or name is None else NN
1301
1237
 
1302
1238
 
1303
- def _name1__(kwds_name, _or_nameof=None):
1239
+ def _name1__(kwds_name, **name__or_nameof):
1304
1240
  '''(INTERNAL) Resolve and set the C{B{name}=NN}.
1305
1241
  '''
1306
- if kwds_name:
1307
- n, kwds_name = _name2__(kwds_name, _or_nameof=_or_nameof)
1308
- if n:
1309
- kwds_name.update(name=n)
1242
+ if kwds_name or name__or_nameof:
1243
+ n, kwds_name = _name2__(kwds_name, **name__or_nameof)
1244
+ kwds_name.update(name=n)
1310
1245
  return kwds_name
1311
1246
 
1312
1247
 
@@ -1406,6 +1341,69 @@ def _Pass(arg, **unused): # PYCHOK no cover
1406
1341
  return arg
1407
1342
 
1408
1343
 
1344
+ def _xjoined_(prefix, name=NN, enquote=True, **name__or_nameof):
1345
+ '''(INTERNAL) Join C{prefix} and non-empty C{name}.
1346
+ '''
1347
+ if name__or_nameof:
1348
+ name = _name__(name, **name__or_nameof)
1349
+ if name and prefix:
1350
+ if enquote:
1351
+ name = repr(name)
1352
+ t = _SPACE_(prefix, name)
1353
+ else:
1354
+ t = prefix or name
1355
+ return t
1356
+
1357
+
1358
+ def _xnamed(inst, name=NN, force=False, **name__or_nameof):
1359
+ '''(INTERNAL) Set the instance' C{.name = B{name}}.
1360
+
1361
+ @arg inst: The instance (C{_Named}).
1362
+ @kwarg name: The name (C{str}).
1363
+ @kwarg force: If C{True}, force rename (C{bool}).
1364
+
1365
+ @return: The B{C{inst}}, renamed if B{C{force}}d
1366
+ or if not named before.
1367
+ '''
1368
+ if name__or_nameof:
1369
+ name = _name__(name, **name__or_nameof)
1370
+ if name and isinstance(inst, _Named):
1371
+ if not inst.name:
1372
+ inst.name = name
1373
+ elif force:
1374
+ inst.rename(name)
1375
+ return inst
1376
+
1377
+
1378
+ def _xother3(inst, other, name=_other_, up=1, **name_other):
1379
+ '''(INTERNAL) Get C{name} and C{up} for a named C{other}.
1380
+ '''
1381
+ if name_other: # and other is None
1382
+ name, other = _xkwds_item2(name_other)
1383
+ elif other and len(other) == 1:
1384
+ name, other = _name__(name), other[0]
1385
+ else:
1386
+ raise _AssertionError(name, other, txt=classname(inst, prefixed=True))
1387
+ return other, name, up
1388
+
1389
+
1390
+ def _xotherError(inst, other, name=_other_, up=1):
1391
+ '''(INTERNAL) Return a C{_TypeError} for an incompatible, named C{other}.
1392
+ '''
1393
+ n = _callname(name, classname(inst, prefixed=True), inst.name, up=up + 1)
1394
+ return _TypeError(name, other, txt=_incompatible(n))
1395
+
1396
+
1397
+ def _xvalid(name, underOK=False):
1398
+ '''(INTERNAL) Check valid attribute name C{name}.
1399
+ '''
1400
+ return bool(name and isstr(name)
1401
+ and name != _name_
1402
+ and (underOK or not name.startswith(_UNDER_))
1403
+ and (not iskeyword(name))
1404
+ and isidentifier(name))
1405
+
1406
+
1409
1407
  __all__ += _ALL_DOCS(_Named,
1410
1408
  _NamedBase, # _NamedDict,
1411
1409
  _NamedEnum, _NamedEnumItem,
pygeodesy/nvectorBase.py CHANGED
@@ -39,7 +39,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdn3
39
39
  from math import fabs, sqrt
40
40
 
41
41
  __all__ = _ALL_LAZY.nvectorBase
42
- __version__ = '24.05.18'
42
+ __version__ = '24.05.31'
43
43
 
44
44
 
45
45
  class NvectorBase(Vector3d): # XXX kept private
@@ -385,7 +385,7 @@ SouthPole = NvectorBase(0, 0, -1, name=_SouthPole_) # South pole (C{Nvector})
385
385
  class _N_vector_(NvectorBase):
386
386
  '''(INTERNAL) Minimal, low-overhead C{n-vector}.
387
387
  '''
388
- def __init__(self, x, y, z, h=0, name=NN):
388
+ def __init__(self, x, y, z, h=0, **name):
389
389
  self._x, self._y, self._z = x, y, z
390
390
  if h:
391
391
  self._h = h
pygeodesy/osgr.py CHANGED
@@ -33,14 +33,14 @@ from pygeodesy.datums import Datums, _ellipsoidal_datum, _WGS84
33
33
  # from pygeodesy.dms import parseDMS2 # _MODS
34
34
  from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
35
35
  from pygeodesy.errors import _parseX, _TypeError, _ValueError, \
36
- _xkwds, _xkwds_get
36
+ _xkwds, _xkwds_get, _xkwds_pop2
37
37
  from pygeodesy.fmath import Fdot, fpowers
38
38
  from pygeodesy.fsums import _Fsumf_
39
39
  from pygeodesy.interns import MISSING, NN, _A_, _COLON_, _COMMA_, \
40
40
  _COMMASPACE_, _DOT_, _ellipsoidal_, \
41
41
  _latlon_, _not_, _SPACE_
42
42
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
43
- from pygeodesy.named import _NamedBase, nameof, _xnamed
43
+ from pygeodesy.named import _name2__, _NamedBase, nameof
44
44
  from pygeodesy.namedTuples import EasNor2Tuple, LatLon2Tuple, \
45
45
  LatLonDatum3Tuple
46
46
  from pygeodesy.props import Property_RO, property_RO
@@ -53,7 +53,7 @@ from pygeodesy.utily import degrees90, degrees180, sincostan3, truncate
53
53
  from math import cos, fabs, radians, sin, sqrt
54
54
 
55
55
  __all__ = _ALL_LAZY.osgr
56
- __version__ = '24.05.13'
56
+ __version__ = '24.05.31'
57
57
 
58
58
  _equivalent_ = 'equivalent'
59
59
  _OSGR_ = 'OSGR'
@@ -194,22 +194,17 @@ class Osgr(_NamedBase):
194
194
  _northing = 0 # Nothing (C{meter})
195
195
  _resolution = 0 # from L{parseOSGR} (C{meter})
196
196
 
197
- def __init__(self, easting, northing, datum=None, name=NN,
198
- resolution=0):
197
+ def __init__(self, easting, northing, datum=None, resolution=0, **name):
199
198
  '''New L{Osgr} coordinate.
200
199
 
201
- @arg easting: Easting from the OS C{National Grid}
202
- origin (C{meter}).
203
- @arg northing: Northing from the OS C{National Grid}
204
- origin (C{meter}).
200
+ @arg easting: Easting from the OS C{National Grid} origin (C{meter}).
201
+ @arg northing: Northing from the OS C{National Grid} origin (C{meter}).
205
202
  @kwarg datum: Override default datum (C{Datums.OSGB36}).
206
- @kwarg name: Optional name (C{str}).
207
- @kwarg resolution: Optional resolution (C{meter}),
208
- C{0} for default.
203
+ @kwarg resolution: Optional resolution (C{meter}), C{0} for default.
204
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
209
205
 
210
- @raise OSGRError: Invalid or negative B{C{easting}} or
211
- B{C{northing}} or B{C{datum}} not an
212
- C{Datums.OSGB36} equivalent.
206
+ @raise OSGRError: Invalid or negative B{C{easting}} or B{C{northing}}
207
+ or B{C{datum}} not an C{Datums.OSGB36} equivalent.
213
208
  '''
214
209
  if datum: # PYCHOK no cover
215
210
  try:
@@ -267,17 +262,17 @@ class Osgr(_NamedBase):
267
262
  '''
268
263
  return self._northing
269
264
 
270
- def parse(self, strOSGR, name=NN):
265
+ def parse(self, strOSGR, **name):
271
266
  '''Parse an OSGR reference to a similar L{Osgr} instance.
272
267
 
273
268
  @arg strOSGR: The OSGR reference (C{str}), see function L{parseOSGR}.
274
- @kwarg name: Optional instance name (C{str}), overriding this name.
269
+ @kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
275
270
 
276
271
  @return: The similar instance (L{Osgr})
277
272
 
278
273
  @raise OSGRError: Invalid B{C{strOSGR}}.
279
274
  '''
280
- return parseOSGR(strOSGR, Osgr=self.classof, name=name or self.name)
275
+ return parseOSGR(strOSGR, Osgr=self.classof, name=self._name__(name))
281
276
 
282
277
  @property_RO
283
278
  def resolution(self):
@@ -496,19 +491,20 @@ def _ll2datum(ll, datum, name):
496
491
  def _ll2LatLon3(ll, LatLon, datum, LatLon_kwds):
497
492
  '''(INTERNAL) Convert C{ll} to C{LatLon}
498
493
  '''
494
+ n = nameof(ll)
499
495
  if LatLon is None:
500
496
  r = _ll2datum(ll, datum, LatLonDatum3Tuple.__name__)
501
- r = LatLonDatum3Tuple(r.lat, r.lon, r.datum)
497
+ r = LatLonDatum3Tuple(r.lat, r.lon, r.datum, name=n)
502
498
  else: # must be ellipsoidal
503
499
  _xsubclassof(_LLEB, LatLon=LatLon)
504
500
  r = _ll2datum(ll, datum, LatLon.__name__)
505
- r = LatLon(r.lat, r.lon, datum=r.datum, **LatLon_kwds)
501
+ r = LatLon(r.lat, r.lon, datum=r.datum, **_xkwds(LatLon_kwds, name=n))
506
502
  if r._iteration != ll._iteration:
507
503
  r._iteration = ll._iteration
508
- return _xnamed(r, nameof(ll))
504
+ return r
509
505
 
510
506
 
511
- def parseOSGR(strOSGR, Osgr=Osgr, name=NN, **Osgr_kwds):
507
+ def parseOSGR(strOSGR, Osgr=Osgr, **name_Osgr_kwds):
512
508
  '''Parse a string representing an OS Grid Reference, consisting
513
509
  of C{"[GD] easting northing"}.
514
510
 
@@ -520,9 +516,9 @@ def parseOSGR(strOSGR, Osgr=Osgr, name=NN, **Osgr_kwds):
520
516
  @arg strOSGR: An OSGR coordinate (C{str}).
521
517
  @kwarg Osgr: Optional class to return the OSGR coordinate
522
518
  (L{Osgr}) or C{None}.
523
- @kwarg name: Optional B{C{Osgr}} name (C{str}).
524
- @kwarg Osgr_kwds: Optional, additional B{C{Osgr}} keyword
525
- arguments, ignored if C{B{Osgr} is None}.
519
+ @kwarg name_Osgr_kwds: Optional C{B{name}=NN} (C{str}) and
520
+ optional, additional B{C{Osgr}} keyword arguments,
521
+ ignored if C{B{Osgr} is None}.
526
522
 
527
523
  @return: An (B{C{Osgr}}) instance or if B{C{Osgr}} is
528
524
  C{None} an L{EasNor2Tuple}C{(easting, northing)}.
@@ -537,7 +533,7 @@ def parseOSGR(strOSGR, Osgr=Osgr, name=NN, **Osgr_kwds):
537
533
  raise ValueError
538
534
  return g
539
535
 
540
- def _OSGR(strOSGR, Osgr, name):
536
+ def _OSGR(strOSGR, Osgr, kwds):
541
537
  s = _splituple(strOSGR.strip())
542
538
  p = len(s)
543
539
  if not p:
@@ -570,20 +566,20 @@ def parseOSGR(strOSGR, Osgr=Osgr, name=NN, **Osgr_kwds):
570
566
  e += E * _100km
571
567
  n += N * _100km
572
568
 
569
+ name, kwds = _name2__(**kwds)
573
570
  if Osgr is None:
574
571
  _ = _MODS.osgr.Osgr(e, n, resolution=m) # validate
575
572
  r = EasNor2Tuple(e, n, name=name)
576
573
  else:
577
- r = Osgr(e, n, name=name,
578
- **_xkwds(Osgr_kwds, resolution=m))
574
+ r = Osgr(e, n, name=name, **_xkwds(kwds, resolution=m))
579
575
  return r
580
576
 
581
- return _parseX(_OSGR, strOSGR, Osgr, name,
577
+ return _parseX(_OSGR, strOSGR, Osgr, name_Osgr_kwds,
582
578
  strOSGR=strOSGR, Error=OSGRError)
583
579
 
584
580
 
585
- def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, name=NN, # MCCABE 14
586
- **prec_Osgr_kwds):
581
+ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, # MCCABE 14
582
+ **prec_name_Osgr_kwds):
587
583
  '''Convert a lat-/longitude point to an OSGR coordinate.
588
584
 
589
585
  @arg latlon: Latitude (C{degrees}) or an (ellipsoidal) geodetic
@@ -597,11 +593,10 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, name=NN, # MCC
597
593
  L{a_f2Tuple}).
598
594
  @kwarg Osgr: Optional class to return the OSGR coordinate
599
595
  (L{Osgr}) or C{None}.
600
- @kwarg name: Optional B{C{Osgr}} name (C{str}).
601
- @kwarg prec_Osgr_kwds: Optional L{truncate} precision
602
- C{B{prec}=ndigits} and/or additional
603
- B{C{Osgr}} keyword arguments, ignored
604
- if C{B{Osgr} is None}.
596
+ @kwarg prec_name_Osgr_kwds: Optional C{B{name}=NN} (C{str}),
597
+ optional L{truncate} precision C{B{prec}=ndigits}
598
+ and additional B{C{Osgr}} keyword arguments,
599
+ ignored if C{B{Osgr} is None}.
605
600
 
606
601
  @return: An (B{C{Osgr}}) instance or if B{C{Osgr}} is C{None}
607
602
  an L{EasNor2Tuple}C{(easting, northing)}.
@@ -615,9 +610,6 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, name=NN, # MCC
615
610
  B{C{datum}}, B{C{Osgr}}, B{C{Osgr_kwds}}
616
611
  or conversion to C{Datums.OSGB36} failed.
617
612
  '''
618
- def _prec_kwds2(prec=MISSING, **kwds):
619
- return prec, kwds
620
-
621
613
  if lon is not None:
622
614
  try:
623
615
  lat, lon = _MODS.dms.parseDMS2(latlon, lon)
@@ -626,8 +618,6 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, name=NN, # MCC
626
618
  raise OSGRError(latlon=latlon, lon=lon, datum=datum, cause=x)
627
619
  elif not isinstance(latlon, _LLEB):
628
620
  raise _TypeError(latlon=latlon, txt=_not_(_ellipsoidal_))
629
- elif not name: # use latlon.name
630
- name = nameof(latlon)
631
621
 
632
622
  NG = _NG
633
623
  # convert latlon to OSGB36 first
@@ -663,22 +653,24 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, name=NN, # MCC
663
653
  d2 / 12 * (_Fsumf_( 5, ta2, 9 * n2) +
664
654
  d2 / 30 * _Fsumf_(61, ta4, 58 * ta2)))).fsum_(m0, NG.nor0)
665
655
 
666
- p, kwds = _prec_kwds2(**prec_Osgr_kwds)
667
- if p is not MISSING:
668
- e = truncate(e, p)
669
- n = truncate(n, p)
656
+ t, kwds = _name2__(prec_name_Osgr_kwds, _or_nameof=latlon)
657
+ if kwds:
658
+ p, kwds = _xkwds_pop2(kwds, prec=MISSING)
659
+ if p is not MISSING:
660
+ e = truncate(e, p)
661
+ n = truncate(n, p)
670
662
 
671
663
  if Osgr is None:
672
664
  _ = _MODS.osgr.Osgr(e, n) # validate
673
- r = EasNor2Tuple(e, n)
665
+ r = EasNor2Tuple(e, n, name=t)
674
666
  else:
675
- r = Osgr(e, n, **kwds) # datum=NG.datum
667
+ r = Osgr(e, n, name=t, **kwds) # datum=NG.datum
676
668
  if lon is None and isinstance(latlon, _LLEB):
677
669
  if kTM:
678
670
  r._latlonTM = latlon # XXX weakref(latlon)?
679
671
  else:
680
672
  r._latlon = latlon # XXX weakref(latlon)?
681
- return _xnamed(r, name or nameof(latlon))
673
+ return r
682
674
 
683
675
 
684
676
  if __name__ == '__main__':
pygeodesy/points.py CHANGED
@@ -38,7 +38,7 @@ from pygeodesy.errors import CrossError, crosserrors, _IndexError, \
38
38
  _xattr, _xkwds, _xkwds_item2, _xkwds_pop2
39
39
  from pygeodesy.fmath import favg, fdot, hypot, Fsum, fsum
40
40
  # from pygeodesy.fsums import Fsum, fsum # from .fmath
41
- from pygeodesy.formy import _bearingTo2, equirectangular_, _spherical_datum
41
+ from pygeodesy.formy import _bearingTo2, equirectangular4, _spherical_datum
42
42
  from pygeodesy.interns import NN, _colinear_, _COMMASPACE_, _composite_, \
43
43
  _DEQUALSPACED_, _ELLIPSIS_, _EW_, _immutable_, \
44
44
  _near_, _no_, _NS_, _point_, _SPACE_, _UNDER_, \
@@ -62,7 +62,7 @@ from pygeodesy.utily import atan2b, degrees90, degrees180, degrees2m, \
62
62
  from math import cos, fabs, fmod as _fmod, radians, sin
63
63
 
64
64
  __all__ = _ALL_LAZY.points
65
- __version__ = '24.05.19'
65
+ __version__ = '24.05.25'
66
66
 
67
67
  _ilat_ = 'ilat'
68
68
  _ilon_ = 'ilon'
@@ -1473,8 +1473,8 @@ def nearestOn5(point, points, closed=False, wrap=False, adjust=True,
1473
1473
  @kwarg closed: Optionally, close the path or polygon (C{bool}).
1474
1474
  @kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
1475
1475
  B{C{points}} (C{bool}).
1476
- @kwarg adjust: See function L{pygeodesy.equirectangular_} (C{bool}).
1477
- @kwarg limit: See function L{pygeodesy.equirectangular_} (C{degrees}),
1476
+ @kwarg adjust: See function L{pygeodesy.equirectangular4} (C{bool}).
1477
+ @kwarg limit: See function L{pygeodesy.equirectangular4} (C{degrees}),
1478
1478
  default C{9 degrees} is about C{1,000 Kmeter} (for mean
1479
1479
  spherical earth radius L{R_KM}).
1480
1480
  @kwarg LatLon_and_kwds: Optional, C{B{LatLon}=None} class to use for
@@ -1490,24 +1490,24 @@ def nearestOn5(point, points, closed=False, wrap=False, adjust=True,
1490
1490
  compass C{degrees}, like function L{pygeodesy.compassAngle}.
1491
1491
 
1492
1492
  @raise LimitError: Lat- and/or longitudinal delta exceeds the B{C{limit}},
1493
- see function L{pygeodesy.equirectangular_}.
1493
+ see function L{pygeodesy.equirectangular4}.
1494
1494
 
1495
1495
  @raise PointsError: Insufficient number of B{C{points}}
1496
1496
 
1497
1497
  @raise TypeError: Some B{C{points}} are not C{LatLon}.
1498
1498
 
1499
- @note: Distances are I{approximated} by function L{pygeodesy.equirectangular_}.
1499
+ @note: Distances are I{approximated} by function L{pygeodesy.equirectangular4}.
1500
1500
  For more accuracy use one of the C{LatLon.nearestOn6} methods.
1501
1501
 
1502
1502
  @see: Function L{pygeodesy.degrees2m}.
1503
1503
  '''
1504
1504
  def _d2yx4(p2, p1, u, alw):
1505
1505
  # w = wrap if (i < (n - 1) or not closed) else False
1506
- # equirectangular_ returns a Distance4Tuple(distance
1506
+ # equirectangular4 returns a Distance4Tuple(distance
1507
1507
  # in degrees squared, delta lat, delta lon, p2.lon
1508
1508
  # unroll/wrap'd); the previous p2.lon unroll/wrap'd
1509
1509
  # is also applied to the next edge's p1.lon
1510
- return equirectangular_(p1.lat, p1.lon + u,
1510
+ return equirectangular4(p1.lat, p1.lon + u,
1511
1511
  p2.lat, p2.lon, **alw)
1512
1512
 
1513
1513
  def _h(p): # get height or default 0
@@ -1604,7 +1604,7 @@ def perimeterOf(points, closed=False, adjust=True, radius=R_M, wrap=True):
1604
1604
  @raise ValueError: Invalid B{C{radius}} or C{B{closed}=False} with
1605
1605
  C{B{points}} a composite.
1606
1606
 
1607
- @note: This perimeter is based on the L{pygeodesy.equirectangular_}
1607
+ @note: This perimeter is based on the L{pygeodesy.equirectangular4}
1608
1608
  distance approximation and is ill-suited for regions exceeding
1609
1609
  several hundred Km or Miles or with near-polar latitudes.
1610
1610
 
@@ -1618,7 +1618,7 @@ def perimeterOf(points, closed=False, adjust=True, radius=R_M, wrap=True):
1618
1618
  if w and c:
1619
1619
  w = not Ps.looped
1620
1620
  # apply previous x2's unroll/wrap'd to new x1
1621
- _, dy, dx, u = equirectangular_(p1.y, p1.x + u,
1621
+ _, dy, dx, u = equirectangular4(p1.y, p1.x + u,
1622
1622
  p2.y, p2.x,
1623
1623
  adjust=a, limit=None,
1624
1624
  wrap=w) # PYCHOK non-seq