pygeodesy 24.7.24__py2.py3-none-any.whl → 24.8.24__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.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/METADATA +20 -19
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/RECORD +57 -57
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +26 -27
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxDST.py +3 -3
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/basics.py +3 -3
- pygeodesy/cartesianBase.py +6 -6
- pygeodesy/constants.py +11 -11
- pygeodesy/css.py +5 -5
- pygeodesy/ellipsoidalBase.py +18 -15
- pygeodesy/ellipsoidalExact.py +2 -2
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +2 -2
- pygeodesy/ellipsoidalNvector.py +2 -2
- pygeodesy/ellipsoidalVincenty.py +7 -6
- pygeodesy/ellipsoids.py +3 -3
- pygeodesy/epsg.py +3 -3
- pygeodesy/fmath.py +2 -1
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +4 -4
- pygeodesy/gars.py +66 -58
- pygeodesy/geodesici.py +4 -10
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +3 -3
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +491 -267
- pygeodesy/geoids.py +298 -316
- pygeodesy/heights.py +176 -194
- pygeodesy/internals.py +39 -6
- pygeodesy/interns.py +2 -3
- pygeodesy/karney.py +2 -2
- pygeodesy/latlonBase.py +14 -8
- pygeodesy/lazily.py +22 -21
- pygeodesy/ltp.py +6 -7
- pygeodesy/ltpTuples.py +12 -6
- pygeodesy/named.py +5 -4
- pygeodesy/namedTuples.py +14 -1
- pygeodesy/osgr.py +7 -7
- pygeodesy/points.py +2 -2
- pygeodesy/resections.py +7 -7
- pygeodesy/rhumb/solve.py +3 -3
- pygeodesy/simplify.py +10 -10
- pygeodesy/sphericalBase.py +3 -3
- pygeodesy/sphericalTrigonometry.py +2 -2
- pygeodesy/streprs.py +3 -3
- pygeodesy/triaxials.py +210 -204
- pygeodesy/units.py +36 -19
- pygeodesy/unitsBase.py +4 -4
- pygeodesy/utmupsBase.py +3 -3
- pygeodesy/vector2d.py +158 -51
- pygeodesy/vector3d.py +13 -52
- pygeodesy/vector3dBase.py +81 -63
- pygeodesy/webmercator.py +3 -3
- pygeodesy/wgrs.py +109 -101
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.24.dist-info}/top_level.txt +0 -0
pygeodesy/vector3d.py
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
u'''Extended 3-D vector class L{Vector3d} and functions.
|
|
5
5
|
|
|
6
|
-
Function L{intersection3d3}, L{intersections2}, L{parse3d}, L{sumOf}
|
|
7
|
-
L{
|
|
6
|
+
Function L{intersection3d3}, L{intersections2}, L{parse3d}, L{sumOf} and
|
|
7
|
+
L{trilaterate3d2}.
|
|
8
8
|
'''
|
|
9
9
|
|
|
10
10
|
from pygeodesy.constants import EPS, EPS0, EPS1, EPS4, INT0, isnear0, \
|
|
@@ -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.
|
|
34
|
+
__version__ = '24.08.18'
|
|
35
35
|
|
|
36
36
|
_vector2d = _MODS.into(vector2d=__name__)
|
|
37
37
|
|
|
@@ -101,7 +101,7 @@ class Vector3d(Vector3dBase):
|
|
|
101
101
|
or C{Vector4Tuple}).
|
|
102
102
|
@arg point3: Third point (C{Cartesian}, L{Vector3d}, C{Vector3Tuple}
|
|
103
103
|
or C{Vector4Tuple}).
|
|
104
|
-
@kwarg circum: If C{True} return the C{circumradius} and C{circumcenter},
|
|
104
|
+
@kwarg circum: If C{True}, return the C{circumradius} and C{circumcenter},
|
|
105
105
|
always, ignoring the I{Meeus}' Type I case (C{bool}).
|
|
106
106
|
@kwarg eps: Tolerance passed to function L{pygeodesy.trilaterate3d2}.
|
|
107
107
|
|
|
@@ -175,7 +175,7 @@ class Vector3d(Vector3dBase):
|
|
|
175
175
|
or C{Vector4Tuple}).
|
|
176
176
|
@arg point3: Third point (C{Cartesian}, L{Vector3d}, C{Vector3Tuple}
|
|
177
177
|
or C{Vector4Tuple}).
|
|
178
|
-
@kwarg circum: If C{True} return the C{circumradius} and C{circumcenter}
|
|
178
|
+
@kwarg circum: If C{True}, return the C{circumradius} and C{circumcenter}
|
|
179
179
|
always, overriding I{Meeus}' Type II case (C{bool}).
|
|
180
180
|
|
|
181
181
|
@return: L{Meeus2Tuple}C{(radius, Type)}, with C{Type} the C{circumcenter}
|
|
@@ -199,7 +199,7 @@ class Vector3d(Vector3dBase):
|
|
|
199
199
|
C{Vector4Tuple}).
|
|
200
200
|
@arg point2: End point (C{Cartesian}, L{Vector3d}, C{Vector3Tuple} or
|
|
201
201
|
C{Vector4Tuple}).
|
|
202
|
-
@kwarg within: If C{True} return the closest point between the given
|
|
202
|
+
@kwarg within: If C{True}, return the closest point between the given
|
|
203
203
|
points, otherwise the closest point on the extended
|
|
204
204
|
line through both points (C{bool}).
|
|
205
205
|
|
|
@@ -406,7 +406,7 @@ def _intersect3d3(start1, end1, start2, end2, eps=EPS, useZ=False): # MCCABE 16
|
|
|
406
406
|
# Get the C{s1'} and C{e1'} corners of a right-angle
|
|
407
407
|
# triangle with the hypotenuse thru C{s1} at bearing
|
|
408
408
|
# C{b1} and the right angle at C{s2}
|
|
409
|
-
dx, dy, d = s2.minus(s1).
|
|
409
|
+
dx, dy, d = s2.minus(s1).xyz3
|
|
410
410
|
if useZ and not isnear0(d): # not supported
|
|
411
411
|
raise IntersectionError(useZ=d, bearing=b1)
|
|
412
412
|
s, c = sincos2d(b1)
|
|
@@ -535,7 +535,7 @@ def intersections2(center1, radius1, center2, radius2, sphere=True, **Vector_and
|
|
|
535
535
|
C{Vector3Tuple} or C{Vector4Tuple}).
|
|
536
536
|
@arg radius2: Radius of the second sphere or circle (same units as the
|
|
537
537
|
B{C{center1}} and B{C{center2}} coordinates).
|
|
538
|
-
@kwarg sphere: If C{True} compute the center and radius of the intersection of
|
|
538
|
+
@kwarg sphere: If C{True}, compute the center and radius of the intersection of
|
|
539
539
|
two spheres. If C{False}, ignore the C{z}-component and compute
|
|
540
540
|
the intersection of two circles (C{bool}).
|
|
541
541
|
@kwarg Vector_and_kwds: Optional class C{B{Vector}=None} to return the
|
|
@@ -657,7 +657,7 @@ def nearestOn(point, point1, point2, within=True, useZ=True, Vector=None, **Vect
|
|
|
657
657
|
C{Vector4Tuple}).
|
|
658
658
|
@arg point2: End point (C{Cartesian}, L{Vector3d}, C{Vector3Tuple} or
|
|
659
659
|
C{Vector4Tuple}).
|
|
660
|
-
@kwarg within: If C{True} return the closest point between both given
|
|
660
|
+
@kwarg within: If C{True}, return the closest point between both given
|
|
661
661
|
points, otherwise the closest point on the extended line
|
|
662
662
|
through both points (C{bool}).
|
|
663
663
|
@kwarg useZ: If C{True}, use the Z components, otherwise force C{z=INT0} (C{bool}).
|
|
@@ -836,45 +836,6 @@ def sumOf(vectors, Vector=Vector3d, **Vector_kwds):
|
|
|
836
836
|
Vector(x, y, z, **_xkwds(Vector_kwds, name__=sumOf)) # .__name__
|
|
837
837
|
|
|
838
838
|
|
|
839
|
-
def trilaterate2d2(x1, y1, radius1, x2, y2, radius2, x3, y3, radius3,
|
|
840
|
-
eps=None, **Vector_and_kwds):
|
|
841
|
-
'''Trilaterate three circles, each given as a (2-D) center and a radius.
|
|
842
|
-
|
|
843
|
-
@arg x1: Center C{x} coordinate of the 1st circle (C{scalar}).
|
|
844
|
-
@arg y1: Center C{y} coordinate of the 1st circle (C{scalar}).
|
|
845
|
-
@arg radius1: Radius of the 1st circle (C{scalar}).
|
|
846
|
-
@arg x2: Center C{x} coordinate of the 2nd circle (C{scalar}).
|
|
847
|
-
@arg y2: Center C{y} coordinate of the 2nd circle (C{scalar}).
|
|
848
|
-
@arg radius2: Radius of the 2nd circle (C{scalar}).
|
|
849
|
-
@arg x3: Center C{x} coordinate of the 3rd circle (C{scalar}).
|
|
850
|
-
@arg y3: Center C{y} coordinate of the 3rd circle (C{scalar}).
|
|
851
|
-
@arg radius3: Radius of the 3rd circle (C{scalar}).
|
|
852
|
-
@kwarg eps: Tolerance to check the trilaterated point I{delta} on all
|
|
853
|
-
3 circles (C{scalar}) or C{None} for no checking.
|
|
854
|
-
@kwarg Vector_and_kwds: Optional class C{B{Vector}=None} to return the
|
|
855
|
-
trilateration and optional, additional B{C{Vector}}
|
|
856
|
-
keyword arguments, otherwise (L{Vector3d}).
|
|
857
|
-
|
|
858
|
-
@return: Trilaterated point as C{B{Vector}(x, y, **B{Vector_kwds})}
|
|
859
|
-
or L{Vector2Tuple}C{(x, y)} if C{B{Vector} is None}..
|
|
860
|
-
|
|
861
|
-
@raise IntersectionError: No intersection, near-concentric or -colinear
|
|
862
|
-
centers, trilateration failed some other way
|
|
863
|
-
or the trilaterated point is off one circle
|
|
864
|
-
by more than B{C{eps}}.
|
|
865
|
-
|
|
866
|
-
@raise UnitError: Invalid B{C{radius1}}, B{C{radius2}} or B{C{radius3}}.
|
|
867
|
-
|
|
868
|
-
@see: U{Issue #49<https://GitHub.com/mrJean1/PyGeodesy/issues/49>},
|
|
869
|
-
U{Find X location using 3 known (X,Y) location using trilateration
|
|
870
|
-
<https://math.StackExchange.com/questions/884807>} and function
|
|
871
|
-
L{pygeodesy.trilaterate3d2}.
|
|
872
|
-
'''
|
|
873
|
-
return _vector2d._trilaterate2d2(x1, y1, radius1,
|
|
874
|
-
x2, y2, radius2,
|
|
875
|
-
x3, y3, radius3, eps=eps, **Vector_and_kwds)
|
|
876
|
-
|
|
877
|
-
|
|
878
839
|
def trilaterate3d2(center1, radius1, center2, radius2, center3, radius3,
|
|
879
840
|
eps=EPS, **Vector_and_kwds):
|
|
880
841
|
'''Trilaterate three spheres, each given as a (3-D) center and a radius.
|
|
@@ -893,10 +854,10 @@ def trilaterate3d2(center1, radius1, center2, radius2, center3, radius3,
|
|
|
893
854
|
and C{z}).
|
|
894
855
|
@kwarg eps: Pertubation tolerance (C{scalar}), same units as C{x},
|
|
895
856
|
C{y} and C{z} or C{None} for no pertubations.
|
|
896
|
-
@kwarg Vector_and_kwds: Optional class C{B{Vector}=None} to return
|
|
897
|
-
trilateration and optional, additional
|
|
898
|
-
keyword arguments, otherwise
|
|
899
|
-
(sub-)class.
|
|
857
|
+
@kwarg Vector_and_kwds: Optional class C{B{Vector}=None} to return
|
|
858
|
+
the trilateration and optional, additional
|
|
859
|
+
B{C{Vector}} keyword arguments, otherwise
|
|
860
|
+
the B{C{center1}}'s (sub-)class.
|
|
900
861
|
|
|
901
862
|
@return: 2-Tuple with two trilaterated points, each a B{C{Vector}}
|
|
902
863
|
instance. Both points are the same instance if all three
|
pygeodesy/vector3dBase.py
CHANGED
|
@@ -8,11 +8,11 @@ A pure Python implementation of vector-based functions by I{(C) Chris Veness
|
|
|
8
8
|
<https://www.Movable-Type.co.UK/scripts/latlong-vectors.html>}.
|
|
9
9
|
'''
|
|
10
10
|
|
|
11
|
-
from pygeodesy.basics import _copysign, islistuple, isscalar, map1, \
|
|
12
|
-
|
|
11
|
+
from pygeodesy.basics import _copysign, islistuple, isscalar, map1, map2, \
|
|
12
|
+
_signOf, _zip
|
|
13
13
|
from pygeodesy.constants import EPS, EPS0, INT0, PI, PI2, _copysignINF, \
|
|
14
14
|
_float0, isnear0, isnear1, isneg0, \
|
|
15
|
-
_pos_self,
|
|
15
|
+
_pos_self, _1_0
|
|
16
16
|
from pygeodesy.errors import CrossError, VectorError, _xcallable, _xError
|
|
17
17
|
from pygeodesy.fmath import euclid_, fdot, hypot_, hypot2_
|
|
18
18
|
from pygeodesy.interns import _coincident_, _colinear_, _COMMASPACE_, _xyz_
|
|
@@ -24,13 +24,12 @@ from pygeodesy.props import deprecated_method, Property, Property_RO, \
|
|
|
24
24
|
property_doc_, property_RO, _update_all
|
|
25
25
|
from pygeodesy.streprs import Fmt, strs, unstr
|
|
26
26
|
from pygeodesy.units import Float, Scalar
|
|
27
|
-
|
|
27
|
+
from pygeodesy.utily import sincos2, atan2, fabs
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
from math import atan2, ceil, fabs, floor, trunc
|
|
29
|
+
from math import ceil as _ceil, floor as _floor, trunc as _trunc
|
|
31
30
|
|
|
32
31
|
__all__ = _ALL_LAZY.vector3dBase
|
|
33
|
-
__version__ = '24.
|
|
32
|
+
__version__ = '24.08.18'
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
@@ -61,7 +60,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
61
60
|
@kwarg ll: Optional latlon reference (C{LatLon}).
|
|
62
61
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
63
62
|
|
|
64
|
-
@raise VectorError: Invalid B{C{x_xyz}}.
|
|
63
|
+
@raise VectorError: Invalid B{C{x_xyz}}, B{C{y}} or B{C{z}}.
|
|
65
64
|
'''
|
|
66
65
|
self._x, \
|
|
67
66
|
self._y, \
|
|
@@ -90,6 +89,8 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
90
89
|
|
|
91
90
|
def __bool__(self): # PYCHOK PyChecker
|
|
92
91
|
'''Is this vector non-zero?
|
|
92
|
+
|
|
93
|
+
@see: Method C{bools}.
|
|
93
94
|
'''
|
|
94
95
|
return bool(self.x or self.y or self.z)
|
|
95
96
|
|
|
@@ -98,7 +99,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
98
99
|
|
|
99
100
|
@return: Ceil-ed (L{Vector3d}).
|
|
100
101
|
'''
|
|
101
|
-
return self._mapped(
|
|
102
|
+
return self._mapped(_ceil)
|
|
102
103
|
|
|
103
104
|
def __cmp__(self, other): # Python 2-
|
|
104
105
|
'''Compare this and an other vector (L{Vector3d}).
|
|
@@ -127,15 +128,15 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
127
128
|
return self.isequalTo(other, eps=EPS0)
|
|
128
129
|
|
|
129
130
|
def __float__(self): # PYCHOK no cover
|
|
130
|
-
'''Not implemented.'''
|
|
131
|
-
return _NotImplemented(self)
|
|
131
|
+
'''Not implemented, see method C{float}.'''
|
|
132
|
+
return _NotImplemented(self) # must return C{float}
|
|
132
133
|
|
|
133
134
|
def __floor__(self): # PYCHOK no cover
|
|
134
135
|
'''Return a vector with the C{floor} of these components.
|
|
135
136
|
|
|
136
137
|
@return: Floor-ed (L{Vector3d}).
|
|
137
138
|
'''
|
|
138
|
-
return self._mapped(
|
|
139
|
+
return self._mapped(_floor)
|
|
139
140
|
|
|
140
141
|
def __floordiv__(self, other): # PYCHOK no cover
|
|
141
142
|
'''Not implemented.'''
|
|
@@ -215,13 +216,8 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
215
216
|
return self._xyz(self.times(scalar))
|
|
216
217
|
|
|
217
218
|
def __int__(self): # PYCHOK no cover
|
|
218
|
-
'''
|
|
219
|
-
|
|
220
|
-
@return: Int-ed (L{Vector3d}).
|
|
221
|
-
'''
|
|
222
|
-
v = self.classof(_0_0)
|
|
223
|
-
v._x, v._y, v._z = map2(int, self.xyz)
|
|
224
|
-
return v
|
|
219
|
+
'''Not implemented, see method C{ints}.'''
|
|
220
|
+
return _NotImplemented(self) # must return C{int}
|
|
225
221
|
|
|
226
222
|
def __ipow__(self, other, *mod): # PYCHOK no cover
|
|
227
223
|
'''Not implemented.'''
|
|
@@ -239,7 +235,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
239
235
|
# def __iter__(self):
|
|
240
236
|
# '''Return an C{iter}ator over this vector's components.
|
|
241
237
|
# '''
|
|
242
|
-
# return iter(self.
|
|
238
|
+
# return iter(self.xyz3)
|
|
243
239
|
|
|
244
240
|
def __itruediv__(self, scalar):
|
|
245
241
|
'''Divide this vector by a scalar I{in-place}, C{this /= B{scalar}}.
|
|
@@ -315,9 +311,9 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
315
311
|
def __neg__(self):
|
|
316
312
|
'''Return the opposite of this vector.
|
|
317
313
|
|
|
318
|
-
@return:
|
|
314
|
+
@return: A negated copy (L{Vector3d})
|
|
319
315
|
'''
|
|
320
|
-
return self.
|
|
316
|
+
return self.negate()
|
|
321
317
|
|
|
322
318
|
def __pos__(self): # PYCHOK no cover
|
|
323
319
|
'''Return this vector I{as-is} or a copy.
|
|
@@ -370,7 +366,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
370
366
|
@return: Rounded (L{Vector3d}).
|
|
371
367
|
'''
|
|
372
368
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
373
|
-
return self.classof(*(round(_, *ndigits) for _ in self.
|
|
369
|
+
return self.classof(*(round(_, *ndigits) for _ in self.xyz3))
|
|
374
370
|
|
|
375
371
|
def __rpow__(self, other, *mod): # PYCHOK no cover
|
|
376
372
|
'''Not implemented.'''
|
|
@@ -423,7 +419,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
423
419
|
|
|
424
420
|
@return: Trunc-ed (L{Vector3d}).
|
|
425
421
|
'''
|
|
426
|
-
return self._mapped(
|
|
422
|
+
return self._mapped(_trunc)
|
|
427
423
|
|
|
428
424
|
if _sys_version_info2 < (3, 0): # PYCHOK no cover
|
|
429
425
|
# <https://docs.Python.org/2/library/operator.html#mapping-operators-to-functions>
|
|
@@ -484,9 +480,14 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
484
480
|
_f2 = fun2
|
|
485
481
|
|
|
486
482
|
xyz = _xyz3(self.apply, other_x, *y_z)
|
|
487
|
-
xyz = (_f2(a, b) for a, b in _zip(self.
|
|
483
|
+
xyz = (_f2(a, b) for a, b in _zip(self.xyz3, xyz)) # strict=True
|
|
488
484
|
return self.classof(*xyz)
|
|
489
485
|
|
|
486
|
+
def bools(self):
|
|
487
|
+
'''Return the vector with C{bool} components.
|
|
488
|
+
'''
|
|
489
|
+
return self._mapped(bool)
|
|
490
|
+
|
|
490
491
|
def cross(self, other, raiser=None, eps0=EPS): # raiser=NN
|
|
491
492
|
'''Compute the cross product of this and an other vector.
|
|
492
493
|
|
|
@@ -502,11 +503,11 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
502
503
|
|
|
503
504
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
504
505
|
'''
|
|
505
|
-
X, Y, Z = self.others(other).
|
|
506
|
-
x, y, z = self.
|
|
507
|
-
xyz = ((y * Z -
|
|
508
|
-
(z * X -
|
|
509
|
-
(x * Y -
|
|
506
|
+
X, Y, Z = self.others(other).xyz3
|
|
507
|
+
x, y, z = self.xyz3
|
|
508
|
+
xyz = ((y * Z - z * Y),
|
|
509
|
+
(z * X - x * Z),
|
|
510
|
+
(x * Y - y * X))
|
|
510
511
|
|
|
511
512
|
if raiser and self.crosserrors and eps0 > 0 \
|
|
512
513
|
and max(map(fabs, xyz)) < eps0:
|
|
@@ -516,7 +517,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
516
517
|
t = _coincident_ if t else _colinear_
|
|
517
518
|
raise CrossError(raiser, s, other=r, txt=t)
|
|
518
519
|
|
|
519
|
-
return self.classof(*xyz)
|
|
520
|
+
return self.classof(*xyz) # name__=self.cross
|
|
520
521
|
|
|
521
522
|
@property_doc_('''raise or ignore L{CrossError} exceptions (C{bool}).''')
|
|
522
523
|
def crosserrors(self):
|
|
@@ -556,8 +557,8 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
556
557
|
|
|
557
558
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
558
559
|
'''
|
|
559
|
-
return self.length2 if other is self else
|
|
560
|
-
|
|
560
|
+
return self.length2 if other is self else fdot(
|
|
561
|
+
self.xyz3, *self.others(other).xyz3)
|
|
561
562
|
|
|
562
563
|
@deprecated_method
|
|
563
564
|
def equals(self, other, units=False): # PYCHOK no cover
|
|
@@ -572,21 +573,31 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
572
573
|
@see: Properties C{length} and C{length2} and function
|
|
573
574
|
L{pygeodesy.euclid_}.
|
|
574
575
|
'''
|
|
575
|
-
return Float(euclid=euclid_(self.
|
|
576
|
+
return Float(euclid=euclid_(*self.xyz3))
|
|
576
577
|
|
|
577
578
|
def equirectangular(self, other):
|
|
578
|
-
'''I{Approximate} the
|
|
579
|
+
'''I{Approximate} the difference between this and an other vector.
|
|
579
580
|
|
|
580
581
|
@arg other: Vector to subtract (C{Vector3dBase}).
|
|
581
582
|
|
|
582
|
-
@return: The
|
|
583
|
+
@return: The length I{squared} of the difference (C{Float}).
|
|
583
584
|
|
|
584
585
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
585
586
|
|
|
586
587
|
@see: Property C{length2}.
|
|
587
588
|
'''
|
|
588
589
|
d = self.minus(other)
|
|
589
|
-
return Float(equirectangular=hypot2_(d.
|
|
590
|
+
return Float(equirectangular=hypot2_(*d.xyz3))
|
|
591
|
+
|
|
592
|
+
def fabs(self):
|
|
593
|
+
'''Return the vector with C{fabs} components.
|
|
594
|
+
'''
|
|
595
|
+
return self._mapped(fabs)
|
|
596
|
+
|
|
597
|
+
def floats(self):
|
|
598
|
+
'''Return the vector with C{float} components.
|
|
599
|
+
'''
|
|
600
|
+
return self._mapped(_float0)
|
|
590
601
|
|
|
591
602
|
@Property
|
|
592
603
|
def _fromll(self):
|
|
@@ -604,7 +615,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
604
615
|
def homogeneous(self):
|
|
605
616
|
'''Get this vector's homogeneous representation (L{Vector3d}).
|
|
606
617
|
'''
|
|
607
|
-
x, y, z = self.
|
|
618
|
+
x, y, z = self.xyz3
|
|
608
619
|
if z:
|
|
609
620
|
x = x / z # /= chokes PyChecker
|
|
610
621
|
y = y / z
|
|
@@ -639,6 +650,11 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
639
650
|
r = self.plus(r.minus(self)._times(f))
|
|
640
651
|
return r
|
|
641
652
|
|
|
653
|
+
def ints(self):
|
|
654
|
+
'''Return the vector with C{int} components.
|
|
655
|
+
'''
|
|
656
|
+
return self._mapped(int)
|
|
657
|
+
|
|
642
658
|
def isconjugateTo(self, other, minum=1, eps=EPS):
|
|
643
659
|
'''Determine whether this and an other vector are conjugates.
|
|
644
660
|
|
|
@@ -657,7 +673,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
657
673
|
'''
|
|
658
674
|
self.others(other)
|
|
659
675
|
n = 0
|
|
660
|
-
for a, b in zip(self.
|
|
676
|
+
for a, b in zip(self.xyz3, other.xyz3):
|
|
661
677
|
if fabs(a + b) < eps and ((a < 0 and b > 0) or
|
|
662
678
|
(a > 0 and b < 0)):
|
|
663
679
|
n += 1 # conjugate
|
|
@@ -685,7 +701,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
685
701
|
d = self.unit().minus(other.unit())
|
|
686
702
|
else:
|
|
687
703
|
d = self.minus(other)
|
|
688
|
-
return max(map(fabs, d.
|
|
704
|
+
return max(map(fabs, d.xyz3)) < eps
|
|
689
705
|
|
|
690
706
|
@Property_RO
|
|
691
707
|
def length(self): # __dict__ value overwritten by Property_RO C{_united}
|
|
@@ -704,9 +720,9 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
704
720
|
return Float(length2=hypot2_(self.x, self.y, self.z))
|
|
705
721
|
|
|
706
722
|
def _mapped(self, func):
|
|
707
|
-
'''(INTERNAL)
|
|
723
|
+
'''(INTERNAL) Apply C{func} to all components.
|
|
708
724
|
'''
|
|
709
|
-
return self.classof(*map2(func, self.
|
|
725
|
+
return self.classof(*map2(func, self.xyz3))
|
|
710
726
|
|
|
711
727
|
def minus(self, other):
|
|
712
728
|
'''Subtract an other vector from this vector.
|
|
@@ -717,8 +733,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
717
733
|
|
|
718
734
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
719
735
|
'''
|
|
720
|
-
|
|
721
|
-
return self._minus(*xyz)
|
|
736
|
+
return self._minus(*self.others(other).xyz3)
|
|
722
737
|
|
|
723
738
|
def _minus(self, x, y, z):
|
|
724
739
|
'''(INTERNAL) Helper for methods C{.minus} and C{.minus_}.
|
|
@@ -742,19 +757,17 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
742
757
|
return self._minus(*_xyz3(self.minus_, other_x, *y_z))
|
|
743
758
|
|
|
744
759
|
def negate(self):
|
|
745
|
-
'''Return
|
|
760
|
+
'''Return the opposite of this vector.
|
|
746
761
|
|
|
747
|
-
@return:
|
|
762
|
+
@return: A negated copy (L{Vector3d})
|
|
748
763
|
'''
|
|
749
764
|
return self.classof(-self.x, -self.y, -self.z)
|
|
750
765
|
|
|
751
|
-
__neg__ = negate # PYCHOK no cover
|
|
752
|
-
|
|
753
766
|
@Property_RO
|
|
754
767
|
def _N_vector(self):
|
|
755
768
|
'''(INTERNAL) Get the (C{nvectorBase._N_vector_})
|
|
756
769
|
'''
|
|
757
|
-
return _MODS.nvectorBase._N_vector_(*self.
|
|
770
|
+
return _MODS.nvectorBase._N_vector_(*self.xyz3, name=self.name)
|
|
758
771
|
|
|
759
772
|
def _other_cmp(self, other):
|
|
760
773
|
'''(INTERNAL) Return the value for comparison.
|
|
@@ -786,8 +799,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
786
799
|
|
|
787
800
|
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
788
801
|
'''
|
|
789
|
-
|
|
790
|
-
return self._plus(*xyz)
|
|
802
|
+
return self._plus(*self.others(other).xyz3)
|
|
791
803
|
|
|
792
804
|
sum = plus # alternate name
|
|
793
805
|
|
|
@@ -825,21 +837,21 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
825
837
|
U{Quaternion-derived rotation matrix<https://WikiPedia.org/wiki/
|
|
826
838
|
Quaternions_and_spatial_rotation#Quaternion-derived_rotation_matrix>}.
|
|
827
839
|
'''
|
|
828
|
-
s, c =
|
|
840
|
+
s, c = sincos2(theta) # rotation angle
|
|
829
841
|
d = _1_0 - c
|
|
830
842
|
if d or s:
|
|
831
843
|
p = self.unit().xyz # point being rotated
|
|
832
844
|
r = self.others(axis=axis).unit() # axis being rotated around
|
|
833
845
|
|
|
834
|
-
ax, ay, az = r.
|
|
835
|
-
bx, by, bz = r.times(d).
|
|
836
|
-
sx, sy, sz = r.times(s).
|
|
846
|
+
ax, ay, az = r.xyz3 # quaternion-derived rotation matrix
|
|
847
|
+
bx, by, bz = r.times(d).xyz3
|
|
848
|
+
sx, sy, sz = r.times(s).xyz3
|
|
837
849
|
|
|
838
850
|
x = fdot(p, ax * bx + c, ax * by - sz, ax * bz + sy)
|
|
839
851
|
y = fdot(p, ay * bx + sz, ay * by + c, ay * bz - sx)
|
|
840
852
|
z = fdot(p, az * bx - sy, az * by + sx, az * bz + c)
|
|
841
853
|
else: # unrotated
|
|
842
|
-
x, y, z = self.
|
|
854
|
+
x, y, z = self.xyz3
|
|
843
855
|
return self.classof(x, y, z)
|
|
844
856
|
|
|
845
857
|
@deprecated_method
|
|
@@ -911,7 +923,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
911
923
|
|
|
912
924
|
@return: Vector as "(x, y, z)" (C{str}).
|
|
913
925
|
'''
|
|
914
|
-
t = sep.join(strs(self.
|
|
926
|
+
t = sep.join(strs(self.xyz3, prec=prec))
|
|
915
927
|
return (fmt % (t,)) if fmt else t
|
|
916
928
|
|
|
917
929
|
def unit(self, ll=None):
|
|
@@ -960,7 +972,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
960
972
|
def xyz(self):
|
|
961
973
|
'''Get the X, Y and Z components (L{Vector3Tuple}C{(x, y, z)}).
|
|
962
974
|
'''
|
|
963
|
-
return _MODS.namedTuples.Vector3Tuple(self.
|
|
975
|
+
return _MODS.namedTuples.Vector3Tuple(*self.xyz3, name=self.name)
|
|
964
976
|
|
|
965
977
|
@xyz.setter # PYCHOK setter!
|
|
966
978
|
def xyz(self, xyz):
|
|
@@ -977,6 +989,12 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
977
989
|
self._x, self._y, self._z = _xyz3(_xyz_, x_xyz, *y_z)
|
|
978
990
|
return self
|
|
979
991
|
|
|
992
|
+
@property_RO
|
|
993
|
+
def xyz3(self):
|
|
994
|
+
'''Get the X, Y and Z components as C{3-tuple}.
|
|
995
|
+
'''
|
|
996
|
+
return self.x, self.y, self.z
|
|
997
|
+
|
|
980
998
|
@property_RO
|
|
981
999
|
def x2y2z2(self):
|
|
982
1000
|
'''Get the X, Y and Z components I{squared} (3-tuple C{(x**2, y**2, z**2)}).
|
|
@@ -1015,15 +1033,15 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
1015
1033
|
|
|
1016
1034
|
|
|
1017
1035
|
def _xyz3(where, x_xyz, *y_z): # in .cartesianBase._rtp3
|
|
1018
|
-
'''(INTERNAL)
|
|
1036
|
+
'''(INTERNAL) Get , Y and Z as 3-tuple C{(x, y, z)}.
|
|
1019
1037
|
'''
|
|
1020
1038
|
try:
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1039
|
+
xyz3 = map1(_float0, x_xyz, *y_z) if y_z else ( # islistuple for Vector*Tuple
|
|
1040
|
+
map2(_float0, x_xyz[:3]) if islistuple(x_xyz, minum=3) else
|
|
1041
|
+
x_xyz.xyz) # .xyz3
|
|
1024
1042
|
except (AttributeError, TypeError, ValueError) as x:
|
|
1025
1043
|
raise _xError(x, unstr(where, x_xyz, *y_z))
|
|
1026
|
-
return
|
|
1044
|
+
return xyz3
|
|
1027
1045
|
|
|
1028
1046
|
|
|
1029
1047
|
__all__ += _ALL_DOCS(Vector3dBase)
|
pygeodesy/webmercator.py
CHANGED
|
@@ -36,7 +36,7 @@ from pygeodesy.utily import degrees90, degrees180
|
|
|
36
36
|
from math import atan, atanh, exp, radians, sin, tanh
|
|
37
37
|
|
|
38
38
|
__all__ = _ALL_LAZY.webmercator
|
|
39
|
-
__version__ = '24.
|
|
39
|
+
__version__ = '24.08.13'
|
|
40
40
|
|
|
41
41
|
# _FalseEasting = 0 # false Easting (C{meter})
|
|
42
42
|
# _FalseNorthing = 0 # false Northing (C{meter})
|
|
@@ -207,7 +207,7 @@ class Wm(_NamedBase):
|
|
|
207
207
|
@kwarg prec: Number of (decimal) digits, unstripped (C{int}).
|
|
208
208
|
@kwarg fmt: Enclosing backets format (C{str}).
|
|
209
209
|
@kwarg sep: Optional separator between name:value pairs (C{str}).
|
|
210
|
-
@kwarg radius: If C{True} include the radius (C{bool}) or
|
|
210
|
+
@kwarg radius: If C{True}, include the radius (C{bool}) or
|
|
211
211
|
C{scalar} to override this WM's radius.
|
|
212
212
|
|
|
213
213
|
@return: This WM as "[x:meter, y:meter]" (C{str}) or as "[x:meter,
|
|
@@ -227,7 +227,7 @@ class Wm(_NamedBase):
|
|
|
227
227
|
@kwarg fmt: Optional C{float} format (C{letter}).
|
|
228
228
|
@kwarg sep: Optional separator to join (C{str}) or C{None}
|
|
229
229
|
to return an unjoined C{tuple} of C{str}s.
|
|
230
|
-
@kwarg radius: If C{True} include the radius (C{bool}) or
|
|
230
|
+
@kwarg radius: If C{True}, include the radius (C{bool}) or
|
|
231
231
|
C{scalar} to override this WM's radius.
|
|
232
232
|
|
|
233
233
|
@return: This WM as "meter meter" (C{str}) or as "meter meter
|