pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.9__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 (71) hide show
  1. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/METADATA +6 -5
  2. PyGeodesy-24.6.9.dist-info/RECORD +116 -0
  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 +54 -67
  9. pygeodesy/cartesianBase.py +138 -147
  10. pygeodesy/constants.py +3 -3
  11. pygeodesy/deprecated/functions.py +9 -3
  12. pygeodesy/ecef.py +67 -72
  13. pygeodesy/ellipsoidalBase.py +18 -56
  14. pygeodesy/ellipsoidalGeodSolve.py +2 -2
  15. pygeodesy/ellipsoidalKarney.py +3 -3
  16. pygeodesy/ellipsoidalNvector.py +7 -7
  17. pygeodesy/ellipsoids.py +6 -5
  18. pygeodesy/errors.py +20 -10
  19. pygeodesy/etm.py +16 -21
  20. pygeodesy/fmath.py +9 -20
  21. pygeodesy/formy.py +60 -74
  22. pygeodesy/frechet.py +13 -14
  23. pygeodesy/fsums.py +60 -26
  24. pygeodesy/geodesicx/__init__.py +1 -1
  25. pygeodesy/geodesicx/__main__.py +2 -2
  26. pygeodesy/geodesicx/gx.py +3 -5
  27. pygeodesy/geodsolve.py +24 -26
  28. pygeodesy/geohash.py +27 -40
  29. pygeodesy/geoids.py +1 -1
  30. pygeodesy/hausdorff.py +17 -18
  31. pygeodesy/heights.py +17 -30
  32. pygeodesy/internals.py +15 -14
  33. pygeodesy/interns.py +3 -9
  34. pygeodesy/iters.py +2 -2
  35. pygeodesy/karney.py +8 -7
  36. pygeodesy/latlonBase.py +189 -176
  37. pygeodesy/lazily.py +92 -56
  38. pygeodesy/lcc.py +2 -2
  39. pygeodesy/ltp.py +93 -55
  40. pygeodesy/ltpTuples.py +304 -240
  41. pygeodesy/mgrs.py +51 -24
  42. pygeodesy/named.py +159 -136
  43. pygeodesy/namedTuples.py +43 -14
  44. pygeodesy/nvectorBase.py +20 -23
  45. pygeodesy/osgr.py +40 -48
  46. pygeodesy/points.py +11 -11
  47. pygeodesy/props.py +29 -16
  48. pygeodesy/rhumb/aux_.py +13 -15
  49. pygeodesy/rhumb/bases.py +12 -5
  50. pygeodesy/rhumb/ekx.py +24 -18
  51. pygeodesy/rhumb/solve.py +20 -70
  52. pygeodesy/simplify.py +16 -16
  53. pygeodesy/solveBase.py +35 -32
  54. pygeodesy/sphericalBase.py +33 -31
  55. pygeodesy/sphericalTrigonometry.py +17 -17
  56. pygeodesy/streprs.py +6 -4
  57. pygeodesy/trf.py +11 -9
  58. pygeodesy/triaxials.py +71 -50
  59. pygeodesy/units.py +40 -65
  60. pygeodesy/unitsBase.py +2 -2
  61. pygeodesy/ups.py +66 -70
  62. pygeodesy/utily.py +7 -6
  63. pygeodesy/utm.py +152 -156
  64. pygeodesy/utmups.py +38 -38
  65. pygeodesy/utmupsBase.py +102 -106
  66. pygeodesy/vector3d.py +34 -36
  67. pygeodesy/vector3dBase.py +12 -9
  68. pygeodesy/webmercator.py +43 -51
  69. PyGeodesy-24.5.24.dist-info/RECORD +0 -116
  70. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.dist-info}/WHEEL +0 -0
  71. {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.9.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.06.09'
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/vector3d.py CHANGED
@@ -25,13 +25,15 @@ from pygeodesy.namedTuples import Intersection3Tuple, NearestOn2Tuple, \
25
25
  # from pygeodesy.streprs import Fmt # from .iters
26
26
  from pygeodesy.units import _fi_j2, _isDegrees, Radius, Radius_
27
27
  from pygeodesy.utily import atan2b, sincos2d
28
- # from pygeodesy.vector2d import .... # in .... below
28
+ # import pygeodesy.vector2d as _vector2d # _MODS.into
29
29
  from pygeodesy.vector3dBase import Vector3dBase
30
30
 
31
31
  # from math import fabs, sqrt # from .fmath
32
32
 
33
33
  __all__ = _ALL_LAZY.vector3d
34
- __version__ = '24.05.21'
34
+ __version__ = '24.06.06'
35
+
36
+ _vector2d = _MODS.into(vector2d=__name__)
35
37
 
36
38
 
37
39
  class Vector3d(Vector3dBase):
@@ -87,7 +89,7 @@ class Vector3d(Vector3dBase):
87
89
  Triangle<https://MathWorld.Wolfram.com/ContactTriangle.html>}.
88
90
  '''
89
91
  try:
90
- return _MODS.vector2d._circin6(self, point2, point3, eps=eps, useZ=True)
92
+ return _vector2d._circin6(self, point2, point3, eps=eps, useZ=True)
91
93
  except (AssertionError, TypeError, ValueError) as x:
92
94
  raise _xError(x, point=self, point2=point2, point3=point3)
93
95
 
@@ -118,8 +120,8 @@ class Vector3d(Vector3dBase):
118
120
  @see: Function L{pygeodesy.circum3} and methods L{circum4_} and L{meeus2}.
119
121
  '''
120
122
  try:
121
- return _MODS.vector2d._circum3(self, point2, point3, circum=circum,
122
- eps=eps, useZ=True, clas=self.classof)
123
+ return _vector2d._circum3(self, point2, point3, circum=circum,
124
+ eps=eps, useZ=True, clas=self.classof)
123
125
  except (AssertionError, TypeError, ValueError) as x:
124
126
  raise _xError(x, point=self, point2=point2, point3=point3, circum=circum)
125
127
 
@@ -143,7 +145,7 @@ class Vector3d(Vector3dBase):
143
145
 
144
146
  @see: Function L{pygeodesy.circum4_} and methods L{circum3} and L{meeus2}.
145
147
  '''
146
- return _MODS.vector2d.circum4_(self, *points, useZ=True, Vector=self.classof)
148
+ return _vector2d.circum4_(self, *points, useZ=True, Vector=self.classof)
147
149
 
148
150
  def iscolinearWith(self, point1, point2, eps=EPS):
149
151
  '''Check whether this and two other (3-D) points are colinear.
@@ -163,7 +165,7 @@ class Vector3d(Vector3dBase):
163
165
  @see: Method L{nearestOn}.
164
166
  '''
165
167
  v = self if self.name else _otherV3d(NN_OK=False, this=self)
166
- return _MODS.vector2d._iscolinearWith(v, point1, point2, eps=eps)
168
+ return _vector2d._iscolinearWith(v, point1, point2, eps=eps)
167
169
 
168
170
  def meeus2(self, point2, point3, circum=False):
169
171
  '''Return the radius and I{Meeus}' Type of the smallest circle I{through}
@@ -186,7 +188,7 @@ class Vector3d(Vector3dBase):
186
188
  @see: Function L{pygeodesy.meeus2} and methods L{circum3} and L{circum4_}.
187
189
  '''
188
190
  try:
189
- return _MODS.vector2d._meeus2(self, point2, point3, circum, clas=self.classof)
191
+ return _vector2d._meeus2(self, point2, point3, circum, clas=self.classof)
190
192
  except (TypeError, ValueError) as x:
191
193
  raise _xError(x, point=self, point2=point2, point3=point3, circum=circum)
192
194
 
@@ -270,7 +272,7 @@ class Vector3d(Vector3dBase):
270
272
  Circles<https://MathWorld.Wolfram.com/TangentCircles.html>}.
271
273
  '''
272
274
  try:
273
- return _MODS.vector2d._radii11ABC(self, point2, point3, useZ=True)[0]
275
+ return _vector2d._radii11ABC(self, point2, point3, useZ=True)[0]
274
276
  except (TypeError, ValueError) as x:
275
277
  raise _xError(x, point=self, point2=point2, point3=point3)
276
278
 
@@ -299,7 +301,7 @@ class Vector3d(Vector3dBase):
299
301
 
300
302
  @see: Function L{pygeodesy.soddy4}.
301
303
  '''
302
- return _MODS.vector2d.soddy4(self, point2, point3, eps=eps, useZ=True)
304
+ return _vector2d.soddy4(self, point2, point3, eps=eps, useZ=True)
303
305
 
304
306
  def trilaterate2d2(self, radius, center2, radius2, center3, radius3, eps=EPS4, z=INT0):
305
307
  '''Trilaterate this and two other circles, each given as a (2-D) center
@@ -335,10 +337,10 @@ class Vector3d(Vector3dBase):
335
337
  return v.x, v.y, r
336
338
 
337
339
  try:
338
- return _MODS.vector2d._trilaterate2d2(*(_xyr3(radius, center=self) +
339
- _xyr3(radius2, center2=center2) +
340
- _xyr3(radius3, center3=center3)),
341
- eps=eps, Vector=self.classof, z=z)
340
+ return _vector2d._trilaterate2d2(*(_xyr3(radius, center=self) +
341
+ _xyr3(radius2, center2=center2) +
342
+ _xyr3(radius3, center3=center3)),
343
+ eps=eps, Vector=self.classof, z=z)
342
344
  except (AssertionError, TypeError, ValueError) as x:
343
345
  raise _xError(x, center=self, radius=radius,
344
346
  center2=center2, radius2=radius2,
@@ -386,10 +388,10 @@ class Vector3d(Vector3dBase):
386
388
  '''
387
389
  try:
388
390
  c1 = _otherV3d(center=self, NN_OK=False)
389
- return _MODS.vector2d._trilaterate3d2(c1, Radius_(radius, low=eps),
390
- center2, radius2,
391
- center3, radius3,
392
- eps=eps, clas=self.classof)
391
+ return _vector2d._trilaterate3d2(c1, Radius_(radius, low=eps),
392
+ center2, radius2,
393
+ center3, radius3,
394
+ eps=eps, clas=self.classof)
393
395
  except (AssertionError, TypeError, ValueError) as x:
394
396
  raise _xError(x, center=self, radius=radius,
395
397
  center2=center2, radius2=radius2,
@@ -643,7 +645,7 @@ def iscolinearWith(point, point1, point2, eps=EPS, useZ=True):
643
645
  @see: Function L{nearestOn}.
644
646
  '''
645
647
  p = _otherV3d(useZ=useZ, point=point)
646
- return _MODS.vector2d._iscolinearWith(p, point1, point2, eps=eps, useZ=useZ)
648
+ return _vector2d._iscolinearWith(p, point1, point2, eps=eps, useZ=useZ)
647
649
 
648
650
 
649
651
  def nearestOn(point, point1, point2, within=True, useZ=True, Vector=None, **Vector_kwds):
@@ -869,9 +871,9 @@ def trilaterate2d2(x1, y1, radius1, x2, y2, radius2, x3, y3, radius3,
869
871
  <https://math.StackExchange.com/questions/884807>} and function
870
872
  L{pygeodesy.trilaterate3d2}.
871
873
  '''
872
- return _MODS.vector2d._trilaterate2d2(x1, y1, radius1,
873
- x2, y2, radius2,
874
- x3, y3, radius3, eps=eps, **Vector_and_kwds)
874
+ return _vector2d._trilaterate2d2(x1, y1, radius1,
875
+ x2, y2, radius2,
876
+ x3, y3, radius3, eps=eps, **Vector_and_kwds)
875
877
 
876
878
 
877
879
  def trilaterate3d2(center1, radius1, center2, radius2, center3, radius3,
@@ -919,27 +921,23 @@ def trilaterate3d2(center1, radius1, center2, radius2, center3, radius3,
919
921
  288825016>} and function L{pygeodesy.trilaterate2d2}.
920
922
  '''
921
923
  try:
922
- return _MODS.vector2d._trilaterate3d2(_otherV3d(center1=center1, NN_OK=False),
923
- Radius_(radius1=radius1, low=eps),
924
- center2, radius2, center3, radius3, eps=eps,
925
- clas=center1.classof, **Vector_and_kwds)
924
+ return _vector2d._trilaterate3d2(_otherV3d(center1=center1, NN_OK=False),
925
+ Radius_(radius1=radius1, low=eps),
926
+ center2, radius2, center3, radius3, eps=eps,
927
+ clas=center1.classof, **Vector_and_kwds)
926
928
  except (AssertionError, TypeError, ValueError) as x:
927
929
  raise _xError(x, center1=center1, radius1=radius1,
928
930
  center2=center2, radius2=radius2,
929
931
  center3=center3, radius3=radius3)
930
932
 
931
933
 
932
- def _xyzhdn3(xyz, height, datum, ll, **name): # in .cartesianBase, .nvectorBase
933
- '''(INTERNAL) Get a C{(h, d, name)} 3-tuple.
934
+ def _xyzhdlln4(xyz, height, datum, ll=None, **name): # in .cartesianBase, .nvectorBase
935
+ '''(INTERNAL) Get a C{(h, d, ll, name)} 4-tuple.
934
936
  '''
935
- h = height or _xattr(xyz, height=None) \
936
- or _xattr(xyz, h=None) \
937
- or _xattr(ll, height=None)
938
-
939
- d = datum or _xattr(xyz, datum=None) \
940
- or _xattr(ll, datum=None)
941
-
942
- return h, d, _name__(name, _or_nameof=xyz)
937
+ _x = _xattr
938
+ h = height or _x(xyz, height=None) or _x(xyz, h=None) or _x(ll, height=None)
939
+ d = datum or _x(xyz, datum=None) or _x(ll, datum=None)
940
+ return h, d, ll, _name__(name, _or_nameof=ll)
943
941
 
944
942
 
945
943
  __all__ += _ALL_DOCS(intersections2, sumOf, Vector3dBase)
pygeodesy/vector3dBase.py CHANGED
@@ -9,7 +9,7 @@ A pure Python implementation of vector-based functions by I{(C) Chris Veness
9
9
  '''
10
10
 
11
11
  from pygeodesy.basics import _copysign, islistuple, isscalar, map1, \
12
- map2, _zip
12
+ map2, _signOf, _zip
13
13
  from pygeodesy.constants import EPS, EPS0, INT0, PI, PI2, _copysignINF, \
14
14
  _float0, isnear0, isnear1, isneg0, \
15
15
  _pos_self, _0_0, _1_0
@@ -30,7 +30,7 @@ from pygeodesy.units import Float, Scalar
30
30
  from math import atan2, ceil, fabs, floor, trunc
31
31
 
32
32
  __all__ = _ALL_LAZY.vector3dBase
33
- __version__ = '24.05.19'
33
+ __version__ = '24.06.07'
34
34
 
35
35
 
36
36
  class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
@@ -107,9 +107,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
107
107
 
108
108
  @raise TypeError: Incompatible B{C{other}} C{type}.
109
109
  '''
110
- n = self.others(other).length
111
- return -1 if self.length < n else (
112
- +1 if self.length > n else 0)
110
+ return _signOf(self.length, self._other_cmp(other))
113
111
 
114
112
  cmp = __cmp__
115
113
 
@@ -156,7 +154,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
156
154
 
157
155
  @raise TypeError: Incompatible B{C{other}} C{type}.
158
156
  '''
159
- return self.length >= self.others(other).length
157
+ return self.length >= self._other_cmp(other)
160
158
 
161
159
  # def __getitem__(self, key):
162
160
  # '''Return C{item} at index or slice C{[B{key}]}.
@@ -172,7 +170,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
172
170
 
173
171
  @raise TypeError: Incompatible B{C{other}} C{type}.
174
172
  '''
175
- return self.length > self.others(other).length
173
+ return self.length > self._other_cmp(other)
176
174
 
177
175
  def __hash__(self): # PYCHOK no cover
178
176
  '''Return this instance' C{hash}.
@@ -261,7 +259,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
261
259
 
262
260
  @raise TypeError: Incompatible B{C{other}} C{type}.
263
261
  '''
264
- return self.length <= self.others(other).length
262
+ return self.length <= self._other_cmp(other)
265
263
 
266
264
  # def __len__(self):
267
265
  # '''Return C{3}, always.
@@ -277,7 +275,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
277
275
 
278
276
  @raise TypeError: Incompatible B{C{other}} C{type}.
279
277
  '''
280
- return self.length < self.others(other).length
278
+ return self.length < self._other_cmp(other)
281
279
 
282
280
  def __matmul__(self, other): # PYCHOK Python 3.5+
283
281
  '''Compute the cross product of this and an other vector, C{this @ B{other}}.
@@ -759,6 +757,11 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
759
757
  '''
760
758
  return _MODS.nvectorBase._N_vector_(*self.xyz, name=self.name)
761
759
 
760
+ def _other_cmp(self, other):
761
+ '''(INTERNAL) Return the value for comparison.
762
+ '''
763
+ return other if isscalar(other) else self.others(other).length
764
+
762
765
  def others(self, *other, **name_other_up):
763
766
  '''Refined class comparison.
764
767