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/utmups.py CHANGED
@@ -16,7 +16,7 @@ by I{Charles Karney}.
16
16
  '''
17
17
  # from pygeodesy.basics import map1 # from .namedTuples
18
18
  # from pygeodesy.datums import _WGS84 # from .utmupsBase
19
- from pygeodesy.errors import _IsnotError, RangeError, _ValueError, _xkwds_get
19
+ from pygeodesy.errors import _IsnotError, RangeError, _ValueError, _xkwds_pop2
20
20
  from pygeodesy.interns import NN, _easting_, _MGRS_, _northing_, _NS_, \
21
21
  _outside_, _range_, _SPACE_, _UPS_, _UTM_
22
22
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
@@ -31,7 +31,7 @@ from pygeodesy.utmupsBase import Fmt, _to4lldn, _to3zBhp, _UPS_ZONE, \
31
31
  _UTMUPS_ZONE_MAX, _WGS84
32
32
 
33
33
  __all__ = _ALL_LAZY.utmups
34
- __version__ = '23.05.03'
34
+ __version__ = '24.05.30'
35
35
 
36
36
  _MGRS_TILE = _100km # in .mgrs.Mgrs.tile
37
37
 
@@ -73,7 +73,7 @@ class UTMUPSError(_ValueError): # XXX (UTMError, UPSError)
73
73
  pass
74
74
 
75
75
 
76
- def parseUTMUPS5(strUTMUPS, datum=_WGS84, Utm=Utm, Ups=Ups, name=NN):
76
+ def parseUTMUPS5(strUTMUPS, datum=_WGS84, Utm=Utm, Ups=Ups, **name):
77
77
  '''Parse a string representing a UTM or UPS coordinate, consisting
78
78
  of C{"zone[band] hemisphere/pole easting northing"}.
79
79
 
@@ -83,13 +83,13 @@ def parseUTMUPS5(strUTMUPS, datum=_WGS84, Utm=Utm, Ups=Ups, name=NN):
83
83
  or C{None}.
84
84
  @kwarg Ups: Optional class to return the UPS coordinate (L{Ups})
85
85
  or C{None}.
86
- @kwarg name: Optional instance name (C{str}).
86
+ @kwarg name: Optional B{C{Utm}} or B{C{Ups}} C{B{name}=NN} (C{str}).
87
87
 
88
- @return: The UTM or UPS instance (B{C{Utm}} or B{C{Ups}}) or
89
- a L{UtmUps5Tuple}C{(zone, hemipole, easting, northing,
90
- band)} if B{C{Utm}} respectively B{C{Ups}} or both are
91
- C{None}. The C{hemipole} is C{'N'|'S'}, the UTM hemisphere
92
- or UPS pole, the UPS projection top/center.
88
+ @return: The UTM or UPS instance (B{C{Utm}} or B{C{Ups}}) or a
89
+ L{UtmUps5Tuple}C{(zone, hemipole, easting, northing, band)}
90
+ if B{C{Utm}} respectively B{C{Ups}} or both are C{None}.
91
+ The C{hemipole} is C{'N'|'S'}, the UTM hemisphere or UPS
92
+ pole, the UPS projection top/center.
93
93
 
94
94
  @raise UTMUPSError: Invalid B{C{strUTMUPS}}.
95
95
 
@@ -100,14 +100,13 @@ def parseUTMUPS5(strUTMUPS, datum=_WGS84, Utm=Utm, Ups=Ups, name=NN):
100
100
  u = parseUTM5(strUTMUPS, datum=datum, Utm=Utm, name=name)
101
101
  except UTMError:
102
102
  u = parseUPS5(strUTMUPS, datum=datum, Ups=Ups, name=name)
103
- return u
104
-
105
103
  except (UTMError, UPSError) as x:
106
104
  raise UTMUPSError(strUTMUPS=strUTMUPS, cause=x)
105
+ return u
107
106
 
108
107
 
109
108
  def toUtmUps8(latlon, lon=None, datum=None, falsed=True, Utm=Utm, Ups=Ups,
110
- pole=NN, name=NN, **cmoff):
109
+ pole=NN, **name_cmoff):
111
110
  '''Convert a lat-/longitude point to a UTM or UPS coordinate.
112
111
 
113
112
  @arg latlon: Latitude (C{degrees}) or an (ellipsoidal)
@@ -122,9 +121,10 @@ def toUtmUps8(latlon, lon=None, datum=None, falsed=True, Utm=Utm, Ups=Ups,
122
121
  or C{None}.
123
122
  @kwarg pole: Optional top/center of UPS (stereographic)
124
123
  projection (C{str}, C{'N[orth]'} or C{'S[outh]'}).
125
- @kwarg name: Optional name (C{str}).
126
- @kwarg cmoff: DEPRECATED, use B{C{falsed}}. Offset longitude
127
- from zone's central meridian, for UTM only (C{bool}).
124
+ @kwarg name_cmoff: Optional B{C{Utm}} or B{C{Ups}} C{B{name}=NN}
125
+ (C{str}) and DEPRECATED keyword argument C{B{cmoff}=True}
126
+ to offset the longitude from the zone's central meridian
127
+ (C{bool}), use B{C{falsed}} instead and I{for UTM only}.
128
128
 
129
129
  @return: The UTM or UPS coordinate (B{C{Utm}} respectively B{C{Ups}})
130
130
  or a L{UtmUps8Tuple}C{(zone, hemipole, easting, northing,
@@ -144,19 +144,18 @@ def toUtmUps8(latlon, lon=None, datum=None, falsed=True, Utm=Utm, Ups=Ups,
144
144
 
145
145
  @see: Functions L{pygeodesy.toUtm8} and L{pygeodesy.toUps8}.
146
146
  '''
147
- lat, lon, d, name = _to4lldn(latlon, lon, datum, name)
148
- z, B, p, lat, lon = utmupsZoneBand5(lat, lon)
149
-
150
- f = falsed and _xkwds_get(cmoff, cmoff=True)
147
+ f, name = _xkwds_pop2(name_cmoff, cmoff=falsed)
148
+ lat, lon, d, n = _to4lldn(latlon, lon, datum, name)
149
+ z, _, p, lat, lon = utmupsZoneBand5(lat, lon)
151
150
  if z == _UPS_ZONE:
152
- u = toUps8(lat, lon, datum=d, falsed=f, Ups=Ups, name=name, pole=pole or p)
151
+ u = toUps8(lat, lon, datum=d, falsed=f, Ups=Ups, name=n, pole=pole or p)
153
152
  else:
154
- u = toUtm8(lat, lon, datum=d, falsed=f, Utm=Utm, name=name)
153
+ u = toUtm8(lat, lon, datum=d, falsed=f, Utm=Utm, name=n)
155
154
  return u
156
155
 
157
156
 
158
157
  def UtmUps(zone, hemipole, easting, northing, band=NN, datum=_WGS84,
159
- falsed=True, name=NN):
158
+ falsed=True, **name):
160
159
  '''Class-like function to create a UTM/UPS coordinate.
161
160
 
162
161
  @kwarg zone: The UTM zone with/-out I{longitudinal} Band or UPS zone C{0}
@@ -167,9 +166,10 @@ def UtmUps(zone, hemipole, easting, northing, band=NN, datum=_WGS84,
167
166
  @arg northing: Northing, see B{C{falsed}} (C{meter}).
168
167
  @kwarg band: Optional, UTM I{latitudinal} C{'C'|'D'|..|'W'|'X'} or UPS
169
168
  I{polar} Band letter C{'A'|'B'|'Y'|'Z'} Band letter (C{str}).
170
- @kwarg datum: Optional, the coordinate's datum (L{Datum}).
171
- @kwarg falsed: Both B{C{easting}} and B{C{northing}} are falsed (C{bool}).
172
- @kwarg name: Optional name (C{str}).
169
+ @kwarg datum: The coordinate's datum (L{Datum}).
170
+ @kwarg falsed: If C{True}, both B{C{easting}} and B{C{northing}} are
171
+ falsed (C{bool}).
172
+ @kwarg name: Optional L{Utm} or L{Ups} C{B{name}=NN} (C{str}).
173
173
 
174
174
  @return: New UTM or UPS instance (L{Utm} or L{Ups}).
175
175
 
@@ -183,7 +183,7 @@ def UtmUps(zone, hemipole, easting, northing, band=NN, datum=_WGS84,
183
183
  z, B, hp = _to3zBhp(zone, band, hemipole=hemipole)
184
184
  U = Ups if z in (_UPS_ZONE, _UPS_ZONE_STR) else Utm
185
185
  return U(z, hp, easting, northing, band=B, datum=datum,
186
- falsed=falsed, name=name)
186
+ falsed=falsed, **name)
187
187
 
188
188
 
189
189
  def utmupsValidate(coord, falsed=False, MGRS=False, Error=UTMUPSError):
@@ -253,10 +253,11 @@ def utmupsValidateOK(coord, falsed=False, ok=True):
253
253
  '''Check a UTM or UPS coordinate.
254
254
 
255
255
  @arg coord: The UTM or UPS coordinate (L{Utm}, L{Ups} or C{5+Tuple}).
256
- @kwarg falsed: C{5+Tuple} easting and northing are falsed (C{bool}).
256
+ @kwarg falsed: Use C{B{falsed}=True} if the C{5+Tuple} easting and
257
+ northing are falsed (C{bool}).
257
258
  @kwarg ok: Result to return if validation passed (B{C{ok}}).
258
259
 
259
- @return: B{C{ok}} if validation passed, the L{UTMUPSError} otherwise.
260
+ @return: B{C{ok}} if validation passed, otherwise the L{UTMUPSError}.
260
261
 
261
262
  @see: Function L{utmupsValidate}.
262
263
  '''
@@ -267,20 +268,19 @@ def utmupsValidateOK(coord, falsed=False, ok=True):
267
268
  return x
268
269
 
269
270
 
270
- def utmupsZoneBand5(lat, lon, cmoff=False, name=NN):
271
+ def utmupsZoneBand5(lat, lon, cmoff=False, **name):
271
272
  '''Return the UTM/UPS zone number, Band letter, hemisphere/pole
272
273
  and clipped lat- and longitude for a given location.
273
274
 
274
275
  @arg lat: Latitude in degrees (C{scalar} or C{str}).
275
276
  @arg lon: Longitude in degrees (C{scalar} or C{str}).
276
- @kwarg cmoff: Offset longitude from the zone's central
277
- meridian, for UTM only (C{bool}).
278
- @kwarg name: Optional name (C{str}).
277
+ @kwarg cmoff: If C{True}, offset longitude from the zone's central
278
+ meridian, I{for UTM only} (C{bool}).
279
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
279
280
 
280
- @return: A L{UtmUpsLatLon5Tuple}C{(zone, band, hemipole,
281
- lat, lon)} where C{hemipole} is C{'N'|'S'}, the
282
- UTM hemisphere or UPS pole, the UPS projection
283
- top/center.
281
+ @return: A L{UtmUpsLatLon5Tuple}C{(zone, band, hemipole, lat, lon)}
282
+ where C{hemipole} is C{'N'|'S'}, the UTM hemisphere or UPS
283
+ pole, the UPS projection top/center.
284
284
 
285
285
  @raise RangeError: If B{C{lat}} outside the valid UTM or UPS bands
286
286
  or if B{C{lat}} or B{C{lon}} outside the valid
@@ -291,9 +291,9 @@ def utmupsZoneBand5(lat, lon, cmoff=False, name=NN):
291
291
  @see: Functions L{pygeodesy.utmZoneBand5} and L{pygeodesy.upsZoneBand5}.
292
292
  '''
293
293
  try:
294
- return utmZoneBand5(lat, lon, cmoff=cmoff, name=name)
294
+ return utmZoneBand5(lat, lon, cmoff=cmoff, **name)
295
295
  except RangeError:
296
- return upsZoneBand5(lat, lon, name=name)
296
+ return upsZoneBand5(lat, lon, **name)
297
297
 
298
298
  # **) MIT License
299
299
  #
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_, \
@@ -12,13 +12,13 @@ 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
14
  from pygeodesy.errors import _or, ParseError, _parseX, _ValueError, \
15
- _xkwds, _xkwds_get, _xkwds_not
16
- # from pygeodesy.internals import _under # from .named
15
+ _xkwds, _xkwds_not
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
- from pygeodesy.named import _NamedBase, nameof, _xnamed, _under
21
+ from pygeodesy.named import _NamedBase, _xnamed, _name__, _under
22
22
  from pygeodesy.namedTuples import EasNor2Tuple, LatLonDatum5Tuple
23
23
  from pygeodesy.props import deprecated_method, property_doc_, _update_all, \
24
24
  deprecated_property_RO, Property_RO, property_RO
@@ -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.13'
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 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,8 +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 = _xkwds_get(convergence, convergence=gamma)
190
100
  if gamma is not self._gamma:
191
101
  self._gamma = Scalar(gamma=gamma, Error=E)
192
102
  if scale is not self._scale:
@@ -207,7 +117,7 @@ class UtmUpsBase(_NamedBase):
207
117
  # self._notOverloaded(callername=_under('Bands'))
208
118
  if band not in self._Bands:
209
119
  t = _or(*sorted(set(map(repr, self._Bands))))
210
- raise self._Error(band=band, txt=_not_(t))
120
+ raise self._Error(band=band, txt_not_=t)
211
121
  self._band = band
212
122
  elif self._band: # reset
213
123
  self._band = NN
@@ -270,7 +180,7 @@ class UtmUpsBase(_NamedBase):
270
180
 
271
181
  @Property_RO
272
182
  def falsed(self):
273
- '''Get easting and northing falsed (C{bool}).
183
+ '''Are easting and northing falsed (C{bool})?
274
184
  '''
275
185
  return self._falsed
276
186
 
@@ -308,9 +218,11 @@ class UtmUpsBase(_NamedBase):
308
218
  ll, _under(_gamma_), _under(_scale_))
309
219
  return _xnamed(r, ll.name)
310
220
 
311
- def _latlon5args(self, ll, _toBand, unfalse, *other):
221
+ def _latlon5args(self, ll, g, k, _toBand, unfalse, *other):
312
222
  '''(INTERNAL) See C{._toLLEB} methods, functions C{ups.toUps8} and C{utm._toXtm8}
313
223
  '''
224
+ ll._gamma = g
225
+ ll._scale = k
314
226
  ll._toLLEB_args = (unfalse,) + other
315
227
  if unfalse:
316
228
  if not self._band:
@@ -416,17 +328,26 @@ class UtmUpsBase(_NamedBase):
416
328
  return t if sep is None else sep.join(t)
417
329
 
418
330
 
419
- 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
420
343
  '''(INTERNAL) I{Un}-center a B{C{utmups}} to its C{lowerleft} by
421
344
  C{B{center} meter} or by a I{guess} if B{C{center}} is C{0}.
422
345
  '''
423
346
  if center:
424
347
  e = n = -center
425
348
  else:
426
- c = 5 # center
427
- for _ in range(3):
428
- c *= 10 # 50, 500, 5000
429
- t = c * 2
349
+ for c in (50, 500, 5000):
350
+ t = c * 2
430
351
  e = int(utmups.easting % t)
431
352
  n = int(utmups.northing % t)
432
353
  if (e == c and n in (c, c - 1)) or \
@@ -437,7 +358,7 @@ def _lowerleft(utmups, center): # by .ellipsoidalBase._lowerleft
437
358
 
438
359
  r = _xkwds_not(None, datum=utmups.datum,
439
360
  gamma=utmups.gamma,
440
- scale=utmups.scale)
361
+ scale=utmups.scale, name=utmups.name)
441
362
  return utmups.classof(utmups.zone, utmups.hemisphere,
442
363
  utmups.easting - e, utmups.northing - n,
443
364
  band=utmups.band, falsed=utmups.falsed, **r)
@@ -487,12 +408,89 @@ def _parseUTMUPS5(strUTMUPS, UPS, Error=ParseError, band=NN, sep=_COMMA_):
487
408
  strUTMUPS=strUTMUPS, Error=Error)
488
409
 
489
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
+
490
429
  def _toMgrs(utmups):
491
430
  '''(INTERNAL) Convert a L{Utm} or L{Ups} to an L{Mgrs} instance.
492
431
  '''
493
432
  return _MODS.mgrs.toMgrs(utmups, datum=utmups.datum, name=utmups.name)
494
433
 
495
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
+
496
494
  __all__ += _ALL_DOCS(UtmUpsBase)
497
495
 
498
496
  # **) MIT License
pygeodesy/vector2d.py CHANGED
@@ -30,7 +30,7 @@ from contextlib import contextmanager
30
30
  # from math import fabs, sqrt # from .fmath
31
31
 
32
32
  __all__ = _ALL_LAZY.vector2d
33
- __version__ = '24.05.04'
33
+ __version__ = '24.05.17'
34
34
 
35
35
  _cA_ = 'cA'
36
36
  _cB_ = 'cB'
@@ -282,11 +282,10 @@ def circum4_(*points, **useZ_Vector_and_kwds):
282
282
  C = map2(float, C)
283
283
  R = map2(float, R) # empty if rk < 4 or n <= 4
284
284
 
285
- n = circum4_.__name__
286
- c = Vector3d(*C[:3], name=n)
287
- r = Radius(sqrt(fsumf_(C[3], *c.x2y2z2)), name=n)
285
+ c = Vector3d(*C[:3], name__=circum4_) # .__name__
286
+ r = Radius(sqrt(fsumf_(C[3], *c.x2y2z2)), name=c.name)
288
287
 
289
- c = _nVc(c, **_xkwds(kwds, clas=ps[0].classof, name=n))
288
+ c = _nVc(c, **_xkwds(kwds, clas=ps[0].classof, name=c.name))
290
289
  return Circum4Tuple(r, c, rk, R)
291
290
 
292
291
 
@@ -416,8 +415,8 @@ class _numpy(object): # see also .formy._idllmn6, .geodesicw._wargs, .latlonBas
416
415
  <https://StackOverflow.com/questions/2992947>} and U{here
417
416
  <https://StackOverflow.com/questions/5889142>}.
418
417
  '''
419
- def _Error(txt=self.null_space2.__name__, **kwds):
420
- return _AssertionError(txt=txt, **kwds)
418
+ def _Error(**kwds):
419
+ return _AssertionError(txt__=self.null_space2, **kwds)
421
420
 
422
421
  np = self.np
423
422
  A = np.array(A)
pygeodesy/vector3d.py CHANGED
@@ -14,11 +14,11 @@ from pygeodesy.errors import IntersectionError, _ValueError, VectorError, \
14
14
  from pygeodesy.fmath import euclid, fabs, fdot, hypot, sqrt, fsum1_
15
15
  # from pygeodesy.fsums import fsum1_ # from .fmath
16
16
  # from pygeodesy.formy import _radical2 # in _intersects2 below
17
- from pygeodesy.interns import NN, _COMMA_, _concentric_, _intersection_, \
18
- _near_, _negative_, _no_, _too_
17
+ from pygeodesy.interns import _COMMA_, _concentric_, _intersection_, \
18
+ _near_, _negative_, _no_, _too_
19
19
  from pygeodesy.iters import PointsIter, Fmt
20
20
  from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
21
- from pygeodesy.named import _xnamed, _xotherError
21
+ from pygeodesy.named import _name__, _name2__, _xnamed, _xotherError
22
22
  from pygeodesy.namedTuples import Intersection3Tuple, NearestOn2Tuple, \
23
23
  NearestOn6Tuple, Vector3Tuple # Vector4Tuple
24
24
  # from pygeodesy.nvectorBase import _nsumOf # _MODS
@@ -31,7 +31,7 @@ from pygeodesy.vector3dBase import Vector3dBase
31
31
  # from math import fabs, sqrt # from .fmath
32
32
 
33
33
  __all__ = _ALL_LAZY.vector3d
34
- __version__ = '24.02.20'
34
+ __version__ = '24.05.21'
35
35
 
36
36
 
37
37
  class Vector3d(Vector3dBase):
@@ -236,18 +236,18 @@ class Vector3d(Vector3dBase):
236
236
  '''
237
237
  return nearestOn6(self, points, closed=closed, useZ=useZ) # Vector=self.classof
238
238
 
239
- def parse(self, str3d, sep=_COMMA_, name=NN):
239
+ def parse(self, str3d, sep=_COMMA_, **name):
240
240
  '''Parse an C{"x, y, z"} string to a L{Vector3d} instance.
241
241
 
242
242
  @arg str3d: X, y and z string (C{str}), see function L{parse3d}.
243
243
  @kwarg sep: Optional separator (C{str}).
244
- @kwarg name: Optional instance name (C{str}), overriding this name.
244
+ @kwarg name: Optional instance C{B{name}=NN} (C{str}), overriding this name.
245
245
 
246
246
  @return: The instance (L{Vector3d}).
247
247
 
248
248
  @raise VectorError: Invalid B{C{str3d}}.
249
249
  '''
250
- return parse3d(str3d, sep=sep, Vector=self.classof, name=name or self.name)
250
+ return parse3d(str3d, sep=sep, Vector=self.classof, name=self._name__(name))
251
251
 
252
252
  def radii11(self, point2, point3):
253
253
  '''Return the radii of the C{Circum-}, C{In-}, I{Soddy} and C{Tangent}
@@ -677,16 +677,15 @@ def nearestOn(point, point1, point2, within=True, useZ=True, Vector=None, **Vect
677
677
  p1 = _otherV3d(useZ=useZ, point1=point1)
678
678
  p2 = _otherV3d(useZ=useZ, point2=point2)
679
679
 
680
- n = nearestOn.__name__
681
680
  p, _ = _nearestOn2(p0, p1, p2, within=within)
682
681
  if Vector is not None:
683
- p = Vector(p.x, p.y, **_xkwds(Vector_kwds, z=p.z, name=n))
682
+ p = Vector(p.x, p.y, **_xkwds(Vector_kwds, z=p.z, name__=nearestOn))
684
683
  elif p is p1:
685
684
  p = point1
686
685
  elif p is p2:
687
686
  p = point2
688
687
  else: # ignore Vector_kwds
689
- p = point.classof(p.x, p.y, _xkwds_get(Vector_kwds, z=p.z), name=n)
688
+ p = point.classof(p.x, p.y, _xkwds_get(Vector_kwds, z=p.z), name__=nearestOn)
690
689
  return p
691
690
 
692
691
 
@@ -765,8 +764,9 @@ def nearestOn6(point, points, closed=False, useZ=True, **Vector_and_kwds): # ep
765
764
  return NearestOn6Tuple(v, sqrt(c2), f, j, s, e)
766
765
 
767
766
 
768
- def _nVc(v, clas=None, name=NN, Vector=None, **Vector_kwds): # in .vector2d
767
+ def _nVc(v, clas=None, Vector=None, **Vector_kwds_name): # in .vector2d
769
768
  # return a named C{Vector} or C{clas} instance
769
+ name, Vector_kwds = _name2__(**Vector_kwds_name)
770
770
  if Vector is not None:
771
771
  v = Vector(v.x, v.y, v.z, **Vector_kwds)
772
772
  elif clas is not None:
@@ -810,7 +810,7 @@ def parse3d(str3d, sep=_COMMA_, Vector=Vector3d, **Vector_kwds):
810
810
  except (TypeError, ValueError) as x:
811
811
  raise VectorError(str3d=str3d, cause=x)
812
812
  return _xnamed((Vector3Tuple(v) if Vector is None else # *v
813
- Vector(*v, **Vector_kwds)), parse3d.__name__)
813
+ Vector(*v, **Vector_kwds)), name__=parse3d) # .__name__
814
814
 
815
815
 
816
816
  def sumOf(vectors, Vector=Vector3d, **Vector_kwds):
@@ -831,9 +831,8 @@ def sumOf(vectors, Vector=Vector3d, **Vector_kwds):
831
831
  except (TypeError, ValueError) as x:
832
832
  raise VectorError(vectors=vectors, Vector=Vector, cause=x)
833
833
  x, y, z = t[:3]
834
- n = sumOf.__name__
835
- return Vector3Tuple(x, y, z, name=n) if Vector is None else \
836
- Vector(x, y, z, **_xkwds(Vector_kwds, name=n))
834
+ return Vector3Tuple(x, y, z, name__=sumOf) if Vector is None else \
835
+ Vector(x, y, z, **_xkwds(Vector_kwds, name__=sumOf)) # .__name__
837
836
 
838
837
 
839
838
  def trilaterate2d2(x1, y1, radius1, x2, y2, radius2, x3, y3, radius3,
@@ -930,7 +929,7 @@ def trilaterate3d2(center1, radius1, center2, radius2, center3, radius3,
930
929
  center3=center3, radius3=radius3)
931
930
 
932
931
 
933
- def _xyzhdn3(xyz, height, datum, ll): # in .cartesianBase, .nvectorBase
932
+ def _xyzhdn3(xyz, height, datum, ll, **name): # in .cartesianBase, .nvectorBase
934
933
  '''(INTERNAL) Get a C{(h, d, name)} 3-tuple.
935
934
  '''
936
935
  h = height or _xattr(xyz, height=None) \
@@ -940,7 +939,7 @@ def _xyzhdn3(xyz, height, datum, ll): # in .cartesianBase, .nvectorBase
940
939
  d = datum or _xattr(xyz, datum=None) \
941
940
  or _xattr(ll, datum=None)
942
941
 
943
- return h, d, _xattr(xyz, name=NN)
942
+ return h, d, _name__(name, _or_nameof=xyz)
944
943
 
945
944
 
946
945
  __all__ += _ALL_DOCS(intersections2, sumOf, Vector3dBase)
pygeodesy/vector3dBase.py CHANGED
@@ -15,8 +15,7 @@ from pygeodesy.constants import EPS, EPS0, INT0, PI, PI2, _copysignINF, \
15
15
  _pos_self, _0_0, _1_0
16
16
  from pygeodesy.errors import CrossError, VectorError, _xcallable, _xError
17
17
  from pygeodesy.fmath import euclid_, fdot, hypot_, hypot2_
18
- from pygeodesy.interns import NN, _coincident_, _colinear_, \
19
- _COMMASPACE_, _xyz_
18
+ from pygeodesy.interns import _coincident_, _colinear_, _COMMASPACE_, _xyz_
20
19
  from pygeodesy.lazily import _ALL_LAZY, _ALL_DOCS, _ALL_MODS as _MODS, \
21
20
  _sys_version_info2
22
21
  from pygeodesy.named import _NamedBase, _NotImplemented, _xother3
@@ -31,7 +30,7 @@ from pygeodesy.units import Float, Scalar
31
30
  from math import atan2, ceil, fabs, floor, trunc
32
31
 
33
32
  __all__ = _ALL_LAZY.vector3dBase
34
- __version__ = '24.05.10'
33
+ __version__ = '24.05.19'
35
34
 
36
35
 
37
36
  class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
@@ -44,7 +43,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
44
43
  # _y = INT0 # Y component
45
44
  # _z = INT0 # Z component
46
45
 
47
- def __init__(self, x_xyz, y=INT0, z=INT0, ll=None, name=NN):
46
+ def __init__(self, x_xyz, y=INT0, z=INT0, ll=None, **name):
48
47
  '''New L{Vector3d} or C{Vector3dBase} instance.
49
48
 
50
49
  The vector may be normalised or use x, y, z for position and
@@ -60,7 +59,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
60
59
  @kwarg z: Z component of vector (C{scalar}), ignored if B{C{x_xyz}}
61
60
  is not C{scalar}, otherwise same units as B{C{x_xyz}}.
62
61
  @kwarg ll: Optional latlon reference (C{LatLon}).
63
- @kwarg name: Optional name (C{str}).
62
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
64
63
 
65
64
  @raise VectorError: Invalid B{C{x_xyz}}.
66
65
  '''