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-24.6.1.dist-info → PyGeodesy-24.6.9.dist-info}/METADATA +2 -2
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.9.dist-info}/RECORD +43 -43
- pygeodesy/__init__.py +1 -1
- pygeodesy/booleans.py +52 -65
- pygeodesy/cartesianBase.py +138 -147
- pygeodesy/ecef.py +46 -52
- pygeodesy/ellipsoidalBase.py +6 -43
- pygeodesy/ellipsoidalNvector.py +7 -7
- pygeodesy/errors.py +2 -2
- pygeodesy/frechet.py +3 -4
- pygeodesy/fsums.py +2 -2
- pygeodesy/geodsolve.py +23 -25
- pygeodesy/geohash.py +14 -27
- pygeodesy/geoids.py +1 -1
- pygeodesy/hausdorff.py +6 -7
- pygeodesy/heights.py +14 -27
- pygeodesy/internals.py +13 -12
- pygeodesy/interns.py +3 -9
- pygeodesy/iters.py +2 -2
- pygeodesy/latlonBase.py +189 -176
- pygeodesy/lazily.py +90 -54
- pygeodesy/lcc.py +2 -2
- pygeodesy/ltp.py +37 -17
- pygeodesy/ltpTuples.py +124 -115
- pygeodesy/mgrs.py +28 -1
- pygeodesy/named.py +92 -67
- pygeodesy/namedTuples.py +43 -14
- pygeodesy/nvectorBase.py +19 -22
- pygeodesy/points.py +2 -2
- pygeodesy/rhumb/solve.py +8 -61
- pygeodesy/solveBase.py +22 -19
- pygeodesy/sphericalBase.py +17 -11
- pygeodesy/streprs.py +6 -4
- pygeodesy/trf.py +3 -3
- pygeodesy/triaxials.py +70 -49
- pygeodesy/units.py +40 -65
- pygeodesy/unitsBase.py +2 -2
- pygeodesy/utily.py +5 -4
- pygeodesy/utmupsBase.py +2 -2
- pygeodesy/vector3d.py +34 -36
- pygeodesy/vector3dBase.py +12 -9
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.9.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.9.dist-info}/top_level.txt +0 -0
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}
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
113
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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})
|
|
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
|
-
|
|
700
|
-
|
|
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
|
|
879
|
-
'''(INTERNAL)
|
|
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
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
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
|
-
|
|
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
|
-
|
|
924
|
-
|
|
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
|
-
|
|
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
|
|
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 .
|
|
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.
|
|
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
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
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.
|
|
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
|
-
#
|
|
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.
|
|
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
|
|
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
|
|
122
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
|
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
|
|
873
|
-
|
|
874
|
-
|
|
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
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
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
|
|
933
|
-
'''(INTERNAL) Get a C{(h, d, name)}
|
|
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
|
-
|
|
936
|
-
|
|
937
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
|
File without changes
|
|
File without changes
|