pygeodesy 24.8.4__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.8.4.dist-info → PyGeodesy-24.8.24.dist-info}/METADATA +16 -15
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.8.24.dist-info}/RECORD +50 -50
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.8.24.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +23 -23
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/basics.py +3 -3
- pygeodesy/cartesianBase.py +5 -5
- pygeodesy/constants.py +11 -11
- 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/epsg.py +3 -3
- pygeodesy/fmath.py +2 -1
- pygeodesy/fsums.py +4 -4
- pygeodesy/gars.py +9 -8
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +3 -3
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +18 -11
- pygeodesy/geoids.py +293 -315
- pygeodesy/heights.py +150 -158
- pygeodesy/internals.py +21 -1
- pygeodesy/interns.py +2 -3
- pygeodesy/latlonBase.py +13 -7
- pygeodesy/lazily.py +6 -6
- pygeodesy/ltp.py +5 -6
- pygeodesy/ltpTuples.py +7 -1
- 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 +207 -201
- pygeodesy/units.py +3 -3
- 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 +20 -22
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.8.24.dist-info}/top_level.txt +0 -0
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
|
pygeodesy/wgrs.py
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
u'''World Geographic Reference System (WGRS) en-/decoding, aka GEOREF.
|
|
5
5
|
|
|
6
|
-
Class L{Georef} and several functions to encode, decode and inspect
|
|
7
|
-
|
|
6
|
+
Class L{Georef} and several functions to encode, decode and inspect WGRS
|
|
7
|
+
(or GEOREF) references.
|
|
8
8
|
|
|
9
9
|
Transcoded from I{Charles Karney}'s C++ class U{Georef
|
|
10
10
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Georef.html>},
|
|
@@ -19,8 +19,8 @@ from pygeodesy.constants import INT0, _float, _off90, _0_001, \
|
|
|
19
19
|
from pygeodesy.dms import parse3llh
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xattr, _xStrError
|
|
21
21
|
from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _COMMA_, \
|
|
22
|
-
_height_, _radius_, _SPACE_
|
|
23
|
-
from pygeodesy.lazily import
|
|
22
|
+
_height_, _INV_, _radius_, _SPACE_
|
|
23
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
|
|
24
24
|
from pygeodesy.named import _name2__, nameof, isstr, Property_RO
|
|
25
25
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLonPrec3Tuple
|
|
26
26
|
# from pygeodesy.props import Property_RO # from .named
|
|
@@ -32,13 +32,12 @@ from pygeodesy.utily import ft2m, m2ft, m2NM
|
|
|
32
32
|
from math import floor
|
|
33
33
|
|
|
34
34
|
__all__ = _ALL_LAZY.wgrs
|
|
35
|
-
__version__ = '24.08.
|
|
35
|
+
__version__ = '24.08.15'
|
|
36
36
|
|
|
37
37
|
_Base = 10
|
|
38
38
|
_BaseLen = 4
|
|
39
39
|
_DegChar = _AtoZnoIO_.tillQ
|
|
40
40
|
_Digits = _0to9_
|
|
41
|
-
_INV_ = 'INV' # INValid
|
|
42
41
|
_LatOrig = -90
|
|
43
42
|
_LatTile = _AtoZnoIO_.tillM
|
|
44
43
|
_LonOrig = -180
|
|
@@ -79,13 +78,12 @@ def _2geostr2(georef):
|
|
|
79
78
|
'''(INTERNAL) Check a georef string.
|
|
80
79
|
'''
|
|
81
80
|
try:
|
|
82
|
-
n,
|
|
81
|
+
n, g = len(georef), georef.upper()
|
|
83
82
|
p, o = divmod(n, 2)
|
|
84
83
|
if o or n < _MinLen or n > _MaxLen \
|
|
85
|
-
or
|
|
86
|
-
or not geostr.isalnum():
|
|
84
|
+
or g.startswith(_INV_) or not g.isalnum():
|
|
87
85
|
raise ValueError()
|
|
88
|
-
return
|
|
86
|
+
return g, _2Precision(p - 1)
|
|
89
87
|
|
|
90
88
|
except (AttributeError, TypeError, ValueError) as x:
|
|
91
89
|
raise WGRSError(Georef.__name__, georef, cause=x)
|
|
@@ -234,8 +232,8 @@ def decode3(georef, center=True):
|
|
|
234
232
|
'''Decode a C{georef} to lat-, longitude and precision.
|
|
235
233
|
|
|
236
234
|
@arg georef: To be decoded (L{Georef} or C{str}).
|
|
237
|
-
@kwarg center: If C{True} the center, otherwise
|
|
238
|
-
lower-left corner (C{bool}).
|
|
235
|
+
@kwarg center: If C{True}, use the georef's center, otherwise
|
|
236
|
+
the south-west, lower-left corner (C{bool}).
|
|
239
237
|
|
|
240
238
|
@return: A L{LatLonPrec3Tuple}C{(lat, lon, precision)}.
|
|
241
239
|
|
|
@@ -287,8 +285,8 @@ def decode5(georef, center=True):
|
|
|
287
285
|
'''Decode a C{georef} to lat-, longitude, precision, height and radius.
|
|
288
286
|
|
|
289
287
|
@arg georef: To be decoded (L{Georef} or C{str}).
|
|
290
|
-
@kwarg center: If C{True} the center, otherwise the
|
|
291
|
-
lower-left corner (C{bool}).
|
|
288
|
+
@kwarg center: If C{True}, use the georef's center, otherwise the
|
|
289
|
+
south-west, lower-left corner (C{bool}).
|
|
292
290
|
|
|
293
291
|
@return: A L{LatLonPrec5Tuple}C{(lat, lon, precision, height, radius)}
|
|
294
292
|
where C{height} and/or C{radius} are C{None} if missing.
|
|
@@ -335,12 +333,11 @@ def encode(lat, lon, precision=3, height=None, radius=None): # MCCABE 14
|
|
|
335
333
|
|
|
336
334
|
@raise WGRSError: Invalid B{C{precision}}, B{C{height}} or B{C{radius}}.
|
|
337
335
|
|
|
338
|
-
@note: The B{C{precision}} value differs from U{Georef<https://
|
|
336
|
+
@note: The B{C{precision}} value differs from I{Karney}'s U{Georef<https://
|
|
339
337
|
GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Georef.html>}.
|
|
340
|
-
The C{georef} length is M{2 * (precision + 1)} and the
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
M{10**(2 - precision)}.
|
|
338
|
+
The C{georef} length is M{2 * (precision + 1)} and the C{georef}
|
|
339
|
+
resolution is I{15°} for B{C{precision}} 0:, I{1°} for 1, I{1′} for 2,
|
|
340
|
+
I{0.1′} for 3, I{0.01′} for 4, ... up to I{10**(2 - precision)′}.
|
|
344
341
|
'''
|
|
345
342
|
def _option(name, m, m2_, K):
|
|
346
343
|
f = Scalar_(m, name=name, Error=WGRSError)
|
|
@@ -413,7 +410,8 @@ def resolution(prec):
|
|
|
413
410
|
'''
|
|
414
411
|
p = Int(prec=prec, Error=WGRSError)
|
|
415
412
|
if p > 1:
|
|
416
|
-
|
|
413
|
+
p = min(p, _MaxPrec) - 1
|
|
414
|
+
r = _1_0 / (pow(_Base, p) * _60_0)
|
|
417
415
|
elif p < 1:
|
|
418
416
|
r = _float_Tile
|
|
419
417
|
else:
|
|
@@ -421,8 +419,8 @@ def resolution(prec):
|
|
|
421
419
|
return r
|
|
422
420
|
|
|
423
421
|
|
|
424
|
-
__all__ +=
|
|
425
|
-
|
|
422
|
+
__all__ += _ALL_DOCS(decode3, decode5, # functions
|
|
423
|
+
encode, precision, resolution)
|
|
426
424
|
|
|
427
425
|
# **) MIT License
|
|
428
426
|
#
|
|
File without changes
|