pygeodesy 24.6.1__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.
pygeodesy/units.py CHANGED
@@ -1,18 +1,17 @@
1
1
 
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
- u'''Various units, all sub-classes of C{Float}, C{Int} and
5
- C{Str} from basic C{float}, C{int} respectively C{str} to
6
- named units as L{Degrees}, L{Feet}, L{Meter}, L{Radians}, etc.
4
+ u'''Various named units, all sub-classes of C{Float}, C{Int} or C{Str} from
5
+ basic C{float}, C{int} respectively C{str} to named units as L{Degrees},
6
+ L{Feet}, L{Meter}, L{Radians}, etc.
7
7
  '''
8
8
 
9
- from pygeodesy.basics import isinstanceof, isscalar, isstr, issubclassof, signOf
9
+ from pygeodesy.basics import isscalar, isstr, issubclassof, signOf, _xsubclassof
10
10
  from pygeodesy.constants import EPS, EPS1, PI, PI2, PI_2, _umod_360, _0_0, \
11
11
  _0_001, _0_5, INT0 # PYCHOK for .mgrs, .namedTuples
12
- from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, \
13
- _toDMS, toDMS
12
+ from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, _toDMS
14
13
  from pygeodesy.errors import _AssertionError, _IsnotError, TRFError, UnitError, \
15
- _xkwds
14
+ _xattr
16
15
  from pygeodesy.interns import NN, _band_, _bearing_, _degrees_, _degrees2_, \
17
16
  _distance_, _E_, _easting_, _epoch_, _EW_, _feet_, \
18
17
  _height_, _lam_, _lat_, _LatLon_, _lon_, _meter_, \
@@ -29,7 +28,7 @@ from pygeodesy.unitsBase import _Error, Float, Fmt, fstr, Int, _arg_name_arg2, \
29
28
  from math import degrees, radians
30
29
 
31
30
  __all__ = _ALL_LAZY.units
32
- __version__ = '24.05.20'
31
+ __version__ = '24.06.10'
33
32
 
34
33
  _negative_falsed_ = 'negative, falsed'
35
34
 
@@ -108,10 +107,9 @@ class Bool(Int, _NamedUnit):
108
107
  @kwarg cls: This class (C{Bool} or sub-class).
109
108
  @kwarg arg: The value (any C{type} convertable to C{bool}).
110
109
  @kwarg name: Optional instance name (C{str}).
111
- @kwarg Error: Optional error to raise, overriding the default
112
- L{UnitError}.
113
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu
114
- of B{C{name}} and B{C{arg}}.
110
+ @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
111
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
112
+ B{C{name}} and B{C{arg}}.
115
113
 
116
114
  @returns: A L{Bool}, a C{bool}-like instance.
117
115
 
@@ -137,13 +135,11 @@ class Bool(Int, _NamedUnit):
137
135
  def toRepr(self, std=False, **unused): # PYCHOK **unused
138
136
  '''Return a representation of this C{Bool}.
139
137
 
140
- @kwarg std: Use the standard C{repr} or the named
141
- representation (C{bool}).
138
+ @kwarg std: Use the standard C{repr} or the named representation (C{bool}).
142
139
 
143
- @note: Use C{env} variable C{PYGEODESY_BOOL_STD_REPR=std}
144
- prior to C{import pygeodesy} to get the standard
145
- C{repr} or set property C{std_repr=False} to always
146
- get the named C{toRepr} representation.
140
+ @note: Use C{env} variable C{PYGEODESY_BOOL_STD_REPR=std} prior to C{import
141
+ pygeodesy} to get the standard C{repr} or set property C{std_repr=False}
142
+ to always get the named C{toRepr} representation.
147
143
  '''
148
144
  r = repr(self._bool_True_or_False)
149
145
  return r if std else self._toRepr(r)
@@ -174,17 +170,16 @@ class Degrees(Float):
174
170
  '''New C{Degrees} instance, see L{Float}.
175
171
 
176
172
  @arg cls: This class (C{Degrees} or sub-class).
177
- @kwarg arg: The value (any scalar C{type} convertable to C{float} or
178
- parsable by L{pygeodesy.parseDMS}).
173
+ @kwarg arg: The value (any scalar C{type} convertable to C{float} or parsable
174
+ by L{pygeodesy.parseDMS}).
179
175
  @kwarg name: Optional instance name (C{str}).
180
- @kwarg Error: Optional error to raise, overriding the default
181
- L{UnitError}.
176
+ @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
182
177
  @kwarg suffix: Optional, valid compass direction suffixes (C{NSEW}).
183
- @kwarg clip: Optional B{C{arg}} range B{C{-clip..+clip}}
184
- (C{degrees} or C{0} or C{None} for unclipped).
178
+ @kwarg clip: Optional B{C{arg}} range B{C{-clip..+clip}} (C{degrees} or C{0}
179
+ or C{None} for unclipped).
185
180
  @kwarg wrap: Optionally adjust the B{C{arg}} value (L{pygeodesy.wrap90},
186
181
  L{pygeodesy.wrap180} or L{pygeodesy.wrap360}).
187
- @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of
182
+ @kwarg name_arg: Optional C{name=arg} keyword argument, inlieu of separate
188
183
  B{C{name}} and B{C{arg}}.
189
184
 
190
185
  @returns: A C{Degrees} instance.
@@ -218,18 +213,18 @@ class Degrees(Float):
218
213
  def toRepr(self, std=False, **prec_fmt_ints): # PYCHOK prec=8, ...
219
214
  '''Return a representation of this C{Degrees}.
220
215
 
221
- @kwarg std: If C{True} return the standard C{repr},
222
- otherwise the named representation (C{bool}).
216
+ @kwarg std: If C{True} return the standard C{repr}, otherwise
217
+ the named representation (C{bool}).
223
218
 
224
219
  @see: Methods L{Degrees.toStr}, L{Float.toRepr} and function
225
- L{pygeodesy.toDMS} for more documentation.
220
+ L{pygeodesy.toDMS} for futher C{prec_fmt_ints} details.
226
221
  '''
227
222
  return Float.toRepr(self, std=std, **prec_fmt_ints)
228
223
 
229
224
  def toStr(self, prec=None, fmt=F__F_, ints=False, **s_D_M_S): # PYCHOK prec=8, ...
230
225
  '''Return this C{Degrees} as standard C{str}.
231
226
 
232
- @see: Function L{pygeodesy.toDMS} for keyword argument details.
227
+ @see: Function L{pygeodesy.toDMS} for futher details.
233
228
  '''
234
229
  if fmt.startswith(_PERCENT_): # use regular formatting
235
230
  p = 8 if prec is None else prec
@@ -288,8 +283,8 @@ class Radians(Float):
288
283
  '''New C{Radians} instance, see L{Float}.
289
284
 
290
285
  @arg cls: This class (C{Radians} or sub-class).
291
- @kwarg arg: The value (any C{type} convertable to C{float} or parsable
292
- by L{pygeodesy.parseRad}).
286
+ @kwarg arg: The value (any C{type} convertable to C{float} or parsable by
287
+ L{pygeodesy.parseRad}).
293
288
  @kwarg name: Optional instance name (C{str}).
294
289
  @kwarg Error: Optional error to raise, overriding the default L{UnitError}.
295
290
  @kwarg suffix: Optional, valid compass direction suffixes (C{NSEW}).
@@ -547,7 +542,7 @@ class FIx(Float_):
547
542
  @arg points: The points (C{LatLon}[], L{Numpy2LatLon}[],
548
543
  L{Tuple2LatLon}[] or C{other}[]).
549
544
  @kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
550
- B{C{points}} (C{bool}) C{None} for backward
545
+ B{C{points}} (C{bool}) or C{None} for backward
551
546
  compatible L{LatLon2Tuple} or B{C{LatLon}} with
552
547
  I{averaged} lat- and longitudes.
553
548
  @kwarg LatLon: Optional class to return the I{intermediate},
@@ -695,10 +690,9 @@ class Meter(Float):
695
690
 
696
691
  @see: Method C{Str.toRepr} and property C{Str.std_repr}.
697
692
 
698
- @note: Use C{env} variable C{PYGEODESY_METER_STD_REPR=std}
699
- prior to C{import pygeodesy} to get the standard
700
- C{repr} or set property C{std_repr=False} to always
701
- get the named C{toRepr} representation.
693
+ @note: Use C{env} variable C{PYGEODESY_METER_STD_REPR=std} prior to C{import
694
+ pygeodesy} to get the standard C{repr} or set property C{std_repr=False}
695
+ to always get the named C{toRepr} representation.
702
696
  '''
703
697
  return self.toRepr(std=self._std_repr)
704
698
 
@@ -875,29 +869,13 @@ def _isScalar(obj):
875
869
  return isscalar(obj) and not isinstance(obj, _NamedUnit)
876
870
 
877
871
 
878
- def _toDegrees(s, *xs, **toDMS_kwds):
879
- '''(INTERNAL) Convert C{xs} from C{Radians} to C{Degrees} or C{toDMS}.
880
- '''
881
- if toDMS_kwds:
882
- toDMS_kwds = _xkwds(toDMS_kwds, ddd=1, pos=NN)
883
-
884
- for x in xs:
885
- if not isinstanceof(x, Degrees, Degrees_):
886
- s = None
887
- x = x.toDegrees()
888
- yield toDMS(x, **toDMS_kwds) if toDMS_kwds else x
889
- yield None if toDMS_kwds else s
890
-
891
-
892
- def _toRadians(s, *xs):
893
- '''(INTERNAL) Convert C{xs} from C{Degrees} to C{Radians}.
872
+ def _toUnit(Unit, arg, name=NN, **Error):
873
+ '''(INTERNAL) Wrap C{arg} in a C{name}d C{Unit}.
894
874
  '''
895
- for x in xs:
896
- if not isinstanceof(x, Radians, Radians_):
897
- s = None
898
- x = x.toRadians()
899
- yield x
900
- yield s
875
+ if not (issubclassof(Unit, _NamedUnit) and isinstance(arg, Unit) and
876
+ _xattr(arg, name=NN) == name):
877
+ arg = Unit(arg, name=name, **Error)
878
+ return arg
901
879
 
902
880
 
903
881
  def _xStrError(*Refs, **name_value_Error):
@@ -910,8 +888,7 @@ def _xStrError(*Refs, **name_value_Error):
910
888
  def _xUnit(units, Base): # in .frechet, .hausdorff
911
889
  '''(INTERNAL) Get C{Unit} from C{Unit} or C{name}, ortherwise C{Base}.
912
890
  '''
913
- if not issubclassof(Base, _NamedUnit):
914
- raise _IsnotError(_NamedUnit.__name__, Base=Base)
891
+ _xsubclassof(_NamedUnit, Base=Base)
915
892
  U = globals().get(units.capitalize(), Base) if isstr(units) else (
916
893
  units if issubclassof(units, Base) else Base)
917
894
  return U if issubclassof(U, Base) else Base
@@ -920,14 +897,12 @@ def _xUnit(units, Base): # in .frechet, .hausdorff
920
897
  def _xUnits(units, Base=_NamedUnit): # in .frechet, .hausdorff
921
898
  '''(INTERNAL) Set property C{units} as C{Unit} or C{Str}.
922
899
  '''
923
- if not issubclassof(Base, _NamedUnit):
924
- raise _IsnotError(_NamedUnit.__name__, Base=Base)
925
- elif issubclassof(units, Base):
900
+ _xsubclassof(_NamedUnit, Base=Base)
901
+ if issubclassof(units, Base):
926
902
  return units
927
903
  elif isstr(units):
928
904
  return Str(units, name=_units_) # XXX Str to _Pass and for backward compatibility
929
- else:
930
- raise _IsnotError(Base.__name__, Str.__name__, str.__name__, units=units)
905
+ raise _IsnotError(*(_.__name__ for _ in (Base, Str, str)), units=units)
931
906
 
932
907
 
933
908
  def _std_repr(*Classes):
pygeodesy/unitsBase.py CHANGED
@@ -14,7 +14,7 @@ from pygeodesy.named import modulename, _Named, property_doc_
14
14
  from pygeodesy.streprs import Fmt, fstr
15
15
 
16
16
  __all__ = _ALL_LAZY.unitsBase
17
- __version__ = '24.05.20'
17
+ __version__ = '24.06.05'
18
18
 
19
19
 
20
20
  class _NamedUnit(_Named):
@@ -107,7 +107,7 @@ class Float(float, _NamedUnit):
107
107
  # XXX the default number of decimals is 10-12 when using
108
108
  # float.__str__(self) with both python 3.8+ and 2.7-, but
109
109
  # float.__repr__(self) shows DIG decimals in python2.7!
110
- # return super(Float, self).__repr__() # see .test.testCss.py
110
+ # return super(Float, self).__repr__() # see .testCss.py
111
111
  return float.__str__(self) # always _std_str_
112
112
 
113
113
  def toRepr(self, std=False, **prec_fmt_ints): # PYCHOK prec=8, ...
pygeodesy/utily.py CHANGED
@@ -27,7 +27,7 @@ from pygeodesy.units import Degrees, Degrees_, Feet, Float, Lam, Lam_, \
27
27
  from math import acos, asin, atan2, cos, degrees, fabs, radians, sin, tan # pow
28
28
 
29
29
  __all__ = _ALL_LAZY.utily
30
- __version__ = '24.05.29'
30
+ __version__ = '24.06.03'
31
31
 
32
32
  # read constant name "_M_Unit" as "meter per Unit"
33
33
  _M_CHAIN = _F( 20.1168) # yard2m(1) * 22
@@ -1002,9 +1002,10 @@ class _Wrap(object):
1002
1002
  def normal(self, setting):
1003
1003
  '''Set L{normal} to C{True}, C{False} or C{None}.
1004
1004
  '''
1005
- t = {True: (_MODS.formy.normal, _MODS.formy.normal_),
1006
- False: (self.wraplatlon, self.wraphilam),
1007
- None: (_passargs, _passargs)}.get(setting, ())
1005
+ m = _MODS.formy
1006
+ t = {True: (m.normal, m.normal_),
1007
+ False: (self.wraplatlon, self.wraphilam),
1008
+ None: (_passargs, _passargs)}.get(setting, ())
1008
1009
  if t:
1009
1010
  self.latlon, self.philam = t
1010
1011
  self._normal = setting
pygeodesy/utmupsBase.py CHANGED
@@ -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.30'
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
@@ -472,7 +472,7 @@ def _to3zBhp(zone, band, hemipole=NN, Error=_ValueError): # in .epsg, .ups, .ut
472
472
  elif not B:
473
473
  return z, B, hp
474
474
 
475
- raise ValueError # _invalid_
475
+ raise ValueError() # _invalid_
476
476
  except (AttributeError, IndexError, TypeError, ValueError) as x:
477
477
  raise Error(zone=zone, band=B, hemipole=hemipole, cause=x)
478
478
 
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