pygeodesy 25.10.10__py2.py3-none-any.whl → 25.12.12__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/__init__.py +25 -12
- pygeodesy/__main__.py +1 -1
- pygeodesy/albers.py +1 -1
- pygeodesy/angles.py +960 -0
- pygeodesy/auxilats/_CX_4.py +1 -1
- pygeodesy/auxilats/_CX_6.py +1 -1
- pygeodesy/auxilats/_CX_8.py +1 -1
- pygeodesy/auxilats/_CX_Rs.py +1 -1
- pygeodesy/auxilats/__init__.py +2 -2
- pygeodesy/auxilats/__main__.py +1 -1
- pygeodesy/auxilats/auxAngle.py +7 -8
- pygeodesy/auxilats/auxDLat.py +1 -1
- pygeodesy/auxilats/auxDST.py +1 -1
- pygeodesy/auxilats/auxLat.py +1 -1
- pygeodesy/auxilats/auxily.py +1 -1
- pygeodesy/azimuthal.py +6 -5
- pygeodesy/basics.py +14 -10
- pygeodesy/booleans.py +8 -33
- pygeodesy/cartesianBase.py +7 -7
- pygeodesy/clipy.py +17 -23
- pygeodesy/constants.py +86 -63
- pygeodesy/css.py +1 -1
- pygeodesy/datums.py +1 -1
- pygeodesy/deprecated/__init__.py +2 -2
- pygeodesy/deprecated/bases.py +1 -1
- pygeodesy/deprecated/classes.py +32 -2
- pygeodesy/deprecated/consterns.py +1 -1
- pygeodesy/deprecated/datum.py +1 -1
- pygeodesy/deprecated/functions.py +1 -1
- pygeodesy/deprecated/nvector.py +1 -1
- pygeodesy/deprecated/rhumbBase.py +1 -1
- pygeodesy/deprecated/rhumbaux.py +1 -1
- pygeodesy/deprecated/rhumbsolve.py +1 -1
- pygeodesy/deprecated/rhumbx.py +1 -1
- pygeodesy/dms.py +1 -1
- pygeodesy/ecef.py +1 -1
- pygeodesy/ecefLocals.py +1 -1
- pygeodesy/elevations.py +1 -1
- pygeodesy/ellipsoidalBase.py +1 -1
- pygeodesy/ellipsoidalBaseDI.py +1 -1
- pygeodesy/ellipsoidalExact.py +1 -1
- pygeodesy/ellipsoidalGeodSolve.py +1 -1
- pygeodesy/ellipsoidalKarney.py +1 -1
- pygeodesy/ellipsoidalNvector.py +1 -1
- pygeodesy/ellipsoidalVincenty.py +1 -1
- pygeodesy/ellipsoids.py +7 -6
- pygeodesy/elliptic.py +1 -1
- pygeodesy/epsg.py +1 -1
- pygeodesy/errors.py +8 -4
- pygeodesy/etm.py +1 -1
- pygeodesy/fmath.py +15 -8
- pygeodesy/formy.py +107 -5
- pygeodesy/frechet.py +1 -1
- pygeodesy/fstats.py +1 -1
- pygeodesy/fsums.py +1 -1
- pygeodesy/gars.py +1 -1
- pygeodesy/geod3solve.py +488 -0
- pygeodesy/geodesici.py +4 -4
- pygeodesy/geodesicw.py +1 -1
- pygeodesy/geodesicx/_C4_24.py +1 -1
- pygeodesy/geodesicx/_C4_27.py +1 -1
- pygeodesy/geodesicx/_C4_30.py +1 -1
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +1 -1
- pygeodesy/geodesicx/gx.py +1 -1
- pygeodesy/geodesicx/gxarea.py +1 -1
- pygeodesy/geodesicx/gxbases.py +1 -1
- pygeodesy/geodesicx/gxline.py +1 -1
- pygeodesy/geodsolve.py +70 -102
- pygeodesy/geohash.py +1 -1
- pygeodesy/geoids.py +1 -1
- pygeodesy/hausdorff.py +1 -1
- pygeodesy/heights.py +1 -1
- pygeodesy/internals.py +3 -3
- pygeodesy/interns.py +3 -3
- pygeodesy/iters.py +1 -1
- pygeodesy/karney.py +132 -116
- pygeodesy/ktm.py +1 -1
- pygeodesy/latlonBase.py +1 -1
- pygeodesy/lazily.py +25 -13
- pygeodesy/lcc.py +1 -1
- pygeodesy/ltp.py +1 -1
- pygeodesy/ltpTuples.py +1 -1
- pygeodesy/mgrs.py +3 -3
- pygeodesy/named.py +14 -9
- pygeodesy/namedTuples.py +1 -1
- pygeodesy/nvectorBase.py +1 -1
- pygeodesy/osgr.py +1 -1
- pygeodesy/points.py +1 -1
- pygeodesy/props.py +1 -1
- pygeodesy/resections.py +1 -1
- pygeodesy/rhumb/__init__.py +8 -6
- pygeodesy/rhumb/aux_.py +1 -1
- pygeodesy/rhumb/bases.py +1 -1
- pygeodesy/rhumb/ekx.py +1 -1
- pygeodesy/rhumb/solve.py +91 -84
- pygeodesy/simplify.py +1 -1
- pygeodesy/solveBase.py +72 -49
- pygeodesy/sphericalBase.py +1 -1
- pygeodesy/sphericalNvector.py +1 -1
- pygeodesy/sphericalTrigonometry.py +1 -1
- pygeodesy/streprs.py +6 -4
- pygeodesy/trf.py +1 -1
- pygeodesy/triaxials/__init__.py +70 -0
- pygeodesy/triaxials/bases.py +935 -0
- pygeodesy/triaxials/conformal3.py +617 -0
- pygeodesy/triaxials/triaxial3.py +969 -0
- pygeodesy/triaxials/triaxial5.py +1220 -0
- pygeodesy/units.py +6 -1
- pygeodesy/unitsBase.py +1 -1
- pygeodesy/ups.py +2 -3
- pygeodesy/utily.py +19 -15
- pygeodesy/utm.py +1 -1
- pygeodesy/utmups.py +1 -1
- pygeodesy/utmupsBase.py +1 -1
- pygeodesy/vector2d.py +2 -2
- pygeodesy/vector3d.py +1 -1
- pygeodesy/vector3dBase.py +195 -51
- pygeodesy/webmercator.py +1 -1
- pygeodesy/wgrs.py +1 -1
- {pygeodesy-25.10.10.dist-info → pygeodesy-25.12.12.dist-info}/METADATA +13 -13
- pygeodesy-25.12.12.dist-info/RECORD +125 -0
- pygeodesy/triaxials.py +0 -1566
- pygeodesy-25.10.10.dist-info/RECORD +0 -119
- {pygeodesy-25.10.10.dist-info → pygeodesy-25.12.12.dist-info}/WHEEL +0 -0
- {pygeodesy-25.10.10.dist-info → pygeodesy-25.12.12.dist-info}/top_level.txt +0 -0
pygeodesy/units.py
CHANGED
|
@@ -820,6 +820,11 @@ def _isMeter(obj, iscalar=True):
|
|
|
820
820
|
return isinstance(obj, _Meters) or (iscalar and _isScalar(obj))
|
|
821
821
|
|
|
822
822
|
|
|
823
|
+
def _isRadians(obj, iscalar=True):
|
|
824
|
+
# Check for valid radian types.
|
|
825
|
+
return isinstance(obj, _Radians) or (iscalar and _isScalar(obj))
|
|
826
|
+
|
|
827
|
+
|
|
823
828
|
def _isRadius(obj, iscalar=True):
|
|
824
829
|
# Check for valid earth radius types.
|
|
825
830
|
return isinstance(obj, _Radii) or (iscalar and _isScalar(obj))
|
|
@@ -872,7 +877,7 @@ __all__ += _ALL_DOCS(_NamedUnit)
|
|
|
872
877
|
|
|
873
878
|
# **) MIT License
|
|
874
879
|
#
|
|
875
|
-
# Copyright (C) 2016-
|
|
880
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
876
881
|
#
|
|
877
882
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
878
883
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/unitsBase.py
CHANGED
|
@@ -350,7 +350,7 @@ __all__ += _ALL_DOCS(_NamedUnit)
|
|
|
350
350
|
|
|
351
351
|
# **) MIT License
|
|
352
352
|
#
|
|
353
|
-
# Copyright (C) 2016-
|
|
353
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
354
354
|
#
|
|
355
355
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
356
356
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/ups.py
CHANGED
|
@@ -22,7 +22,7 @@ other than C{"std"}, zones C{'A'} and C{'Y'} are used for negative, west longitu
|
|
|
22
22
|
'''
|
|
23
23
|
|
|
24
24
|
# from pygeodesy.basics import neg as _neg # from .dms
|
|
25
|
-
from pygeodesy.constants import EPS, EPS0, _EPSmin as _Tol90, \
|
|
25
|
+
from pygeodesy.constants import EPS, EPS0, _EPSmin as _Tol90, _K0_UPS, \
|
|
26
26
|
isnear90, _0_0, _0_5, _1_0, _2_0
|
|
27
27
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
28
28
|
from pygeodesy.dms import degDMS, _neg, parseDMS2
|
|
@@ -53,7 +53,6 @@ __version__ = '25.04.14'
|
|
|
53
53
|
|
|
54
54
|
_BZ_UPS = _envPYGEODESY('UPS_POLES', _std_) == _std_
|
|
55
55
|
_Falsing = Meter(2000e3) # false easting and northing (C{meter})
|
|
56
|
-
_K0_UPS = Float(_K0_UPS= 0.994) # scale factor at central meridian
|
|
57
56
|
_K1_UPS = Float(_K1_UPS=_1_0) # rescale point scale factor
|
|
58
57
|
|
|
59
58
|
|
|
@@ -509,7 +508,7 @@ def upsZoneBand5(lat, lon, strict=True, **name):
|
|
|
509
508
|
|
|
510
509
|
# **) MIT License
|
|
511
510
|
#
|
|
512
|
-
# Copyright (C) 2016-
|
|
511
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
513
512
|
#
|
|
514
513
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
515
514
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/utily.py
CHANGED
|
@@ -16,7 +16,7 @@ from pygeodesy.constants import EPS, EPS0, NAN, PI, PI2, PI_2, PI_4, PI_6, R_M,
|
|
|
16
16
|
_M_KM, _M_NM, _M_SM, _0_0, _0_5, _1_0, _N_1_0, \
|
|
17
17
|
_10_0, _90_0, _180_0, _360_0, _copysign_0_0, \
|
|
18
18
|
_copysignINF, _float, _isfinite, isnan, isnear0, \
|
|
19
|
-
_over_1, _umod_360, _umod_PI2
|
|
19
|
+
_over_1, _umod_360, _umod_PI2, OVERFLOW
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xkwds, _xkwds_get
|
|
21
21
|
from pygeodesy.internals import _Enum, _passargs, typename
|
|
22
22
|
from pygeodesy.interns import _edge_, _radians_, _semi_circular_, _SPACE_
|
|
@@ -28,7 +28,7 @@ from math import acos, asin, asinh, atan2 as _atan2, cos, degrees, fabs, \
|
|
|
28
28
|
radians, sin, sinh, tan as _tan # pow
|
|
29
29
|
|
|
30
30
|
__all__ = _ALL_LAZY.utily
|
|
31
|
-
__version__ = '25.
|
|
31
|
+
__version__ = '25.11.09'
|
|
32
32
|
|
|
33
33
|
# sqrt(3) <https://WikiPedia.org/wiki/Square_root_of_3>
|
|
34
34
|
_COS_30, _SIN_30 = 0.86602540378443864676, _0_5 # sqrt(3) / 2
|
|
@@ -807,15 +807,16 @@ def _sin0cos2(q, r, sign):
|
|
|
807
807
|
return s, c
|
|
808
808
|
|
|
809
809
|
|
|
810
|
-
def SinCos2(x):
|
|
810
|
+
def SinCos2(x, unit=Radians):
|
|
811
811
|
'''Get C{sin} and C{cos} of I{typed} angle.
|
|
812
812
|
|
|
813
813
|
@arg x: Angle (L{Degrees}, L{Radians} or scalar C{radians}).
|
|
814
|
+
@kwarg unit: The C{B{x}} unit (L{Degrees}, L{Radians}).
|
|
814
815
|
|
|
815
816
|
@return: 2-Tuple (C{sin(B{x})}, C{cos(B{x})}).
|
|
816
817
|
'''
|
|
817
|
-
return sincos2d(x) if isinstanceof(x, Degrees, Degrees_) else (
|
|
818
|
-
# sincos2(x) if isinstanceof(x, Radians, Radians_) else
|
|
818
|
+
return sincos2d(x) if unit is Degrees or unit is degrees or isinstanceof(x, Degrees, Degrees_) else (
|
|
819
|
+
# sincos2(x) if unit is Radians or unit is radians or isinstanceof(x, Radians, Radians_) else
|
|
819
820
|
sincos2(Radians(x))) # assume C{radians}
|
|
820
821
|
|
|
821
822
|
|
|
@@ -996,13 +997,14 @@ def tan_(*rads, **raiser_kwds):
|
|
|
996
997
|
yield _nonfinite(tan_, r, **raiser_kwds)
|
|
997
998
|
|
|
998
999
|
|
|
999
|
-
def tand(deg, **
|
|
1000
|
+
def tand(deg, **raiser_clamp_kwds):
|
|
1000
1001
|
'''Return the C{tangent} of an angle in C{degrees}.
|
|
1001
1002
|
|
|
1002
1003
|
@arg deg: Angle (C{degrees}).
|
|
1003
|
-
@kwarg
|
|
1004
|
-
ValueErrors and
|
|
1005
|
-
ValueError keyword
|
|
1004
|
+
@kwarg raiser_clamp_kwds: Use C{B{raiser}=False} to avoid
|
|
1005
|
+
ValueErrors, C{B{clamp}=}L{OVERFLOW} and
|
|
1006
|
+
optional, additional ValueError keyword
|
|
1007
|
+
argments.
|
|
1006
1008
|
|
|
1007
1009
|
@return: C{tan(B{deg})}.
|
|
1008
1010
|
|
|
@@ -1011,10 +1013,10 @@ def tand(deg, **raiser_kwds):
|
|
|
1011
1013
|
try:
|
|
1012
1014
|
return _tanu(*sincos2d(deg))
|
|
1013
1015
|
except ZeroDivisionError:
|
|
1014
|
-
return _nonfinite(tand, deg, **
|
|
1016
|
+
return _nonfinite(tand, deg, **raiser_clamp_kwds)
|
|
1015
1017
|
|
|
1016
1018
|
|
|
1017
|
-
def tand_(*degs, **
|
|
1019
|
+
def tand_(*degs, **raiser_clamp_kwds):
|
|
1018
1020
|
'''Yield the C{tangent} of angle(s) in C{degrees}.
|
|
1019
1021
|
|
|
1020
1022
|
@arg degs: One or more angles (each in C{degrees}).
|
|
@@ -1025,9 +1027,9 @@ def tand_(*degs, **raiser_kwds):
|
|
|
1025
1027
|
'''
|
|
1026
1028
|
try:
|
|
1027
1029
|
for d in degs:
|
|
1028
|
-
yield _tanu(*sincos2d(d))
|
|
1030
|
+
yield _tanu(*sincos2d(d), **raiser_clamp_kwds)
|
|
1029
1031
|
except ZeroDivisionError:
|
|
1030
|
-
yield _nonfinite(tand_, d, **
|
|
1032
|
+
yield _nonfinite(tand_, d, **raiser_clamp_kwds)
|
|
1031
1033
|
|
|
1032
1034
|
|
|
1033
1035
|
def tanPI_2_2(rad):
|
|
@@ -1041,7 +1043,7 @@ def tanPI_2_2(rad):
|
|
|
1041
1043
|
NAN if isnan(rad) else _copysign(_90_0, rad))
|
|
1042
1044
|
|
|
1043
1045
|
|
|
1044
|
-
def _tanu(s, c):
|
|
1046
|
+
def _tanu(s, c, clamp=OVERFLOW, **unused):
|
|
1045
1047
|
'''(INTERNAL) Helper for functions C{_cotu}, C{sincostan3},
|
|
1046
1048
|
C{sincostan3d}, C{tan}, C{tan_}, C{tand} and C{tand_}.
|
|
1047
1049
|
'''
|
|
@@ -1051,6 +1053,8 @@ def _tanu(s, c):
|
|
|
1051
1053
|
raise ZeroDivisionError()
|
|
1052
1054
|
else:
|
|
1053
1055
|
t = _over_1(s, c)
|
|
1056
|
+
if clamp:
|
|
1057
|
+
t = min(clamp, max(t, -clamp))
|
|
1054
1058
|
return t
|
|
1055
1059
|
|
|
1056
1060
|
|
|
@@ -1383,7 +1387,7 @@ def yard2m(yards):
|
|
|
1383
1387
|
|
|
1384
1388
|
# **) MIT License
|
|
1385
1389
|
#
|
|
1386
|
-
# Copyright (C) 2016-
|
|
1390
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1387
1391
|
#
|
|
1388
1392
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1389
1393
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/utm.py
CHANGED
|
@@ -733,7 +733,7 @@ def utmZoneBand5(lat, lon, cmoff=False, **name):
|
|
|
733
733
|
|
|
734
734
|
# **) MIT License
|
|
735
735
|
#
|
|
736
|
-
# Copyright (C) 2016-
|
|
736
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
737
737
|
#
|
|
738
738
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
739
739
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/utmups.py
CHANGED
|
@@ -294,7 +294,7 @@ def utmupsZoneBand5(lat, lon, cmoff=False, **name):
|
|
|
294
294
|
|
|
295
295
|
# **) MIT License
|
|
296
296
|
#
|
|
297
|
-
# Copyright (C) 2016-
|
|
297
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
298
298
|
#
|
|
299
299
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
300
300
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/utmupsBase.py
CHANGED
|
@@ -586,7 +586,7 @@ __all__ += _ALL_DOCS(UtmUpsBase)
|
|
|
586
586
|
|
|
587
587
|
# **) MIT License
|
|
588
588
|
#
|
|
589
|
-
# Copyright (C) 2016-
|
|
589
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
590
590
|
#
|
|
591
591
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
592
592
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/vector2d.py
CHANGED
|
@@ -641,7 +641,7 @@ def triaxum5(points, useZ=True):
|
|
|
641
641
|
A = []
|
|
642
642
|
for i, p in enumerate(ps):
|
|
643
643
|
v = _otherV3d(useZ=useZ, i=i, points=p)
|
|
644
|
-
A.append(v.
|
|
644
|
+
A.append(v.x2y2z23)
|
|
645
645
|
|
|
646
646
|
with _numpy(triaxum5, n=n) as _np:
|
|
647
647
|
A = _np.array(A)
|
|
@@ -884,7 +884,7 @@ def _tri5perturbs(eps, r):
|
|
|
884
884
|
|
|
885
885
|
# **) MIT License
|
|
886
886
|
#
|
|
887
|
-
# Copyright (C) 2016-
|
|
887
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
888
888
|
#
|
|
889
889
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
890
890
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/vector3d.py
CHANGED
|
@@ -914,7 +914,7 @@ __all__ += _ALL_DOCS(intersections2, sumOf, Vector3dBase)
|
|
|
914
914
|
|
|
915
915
|
# **) MIT License
|
|
916
916
|
#
|
|
917
|
-
# Copyright (C) 2016-
|
|
917
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
918
918
|
#
|
|
919
919
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
920
920
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/vector3dBase.py
CHANGED
|
@@ -10,9 +10,9 @@ A pure Python implementation of vector-based functions by I{(C) Chris Veness
|
|
|
10
10
|
|
|
11
11
|
from pygeodesy.basics import _copysign, islistuple, isscalar, \
|
|
12
12
|
map1, map2, _signOf, _zip
|
|
13
|
-
from pygeodesy.constants import EPS, EPS0, INT0, PI, PI2, \
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
from pygeodesy.constants import EPS, EPS0, INT0, PI, PI2, _1_0, \
|
|
14
|
+
_copysignINF, isnear0, isnear1, \
|
|
15
|
+
_flipsign, _float0, _pos_self
|
|
16
16
|
from pygeodesy.errors import CrossError, VectorError, _xcallable, _xError
|
|
17
17
|
from pygeodesy.fmath import euclid_, fdot, fdot_, hypot_, hypot2_ # _MODS.fmath.fma
|
|
18
18
|
from pygeodesy.interns import _coincident_, _colinear_, _COMMASPACE_, _xyz_
|
|
@@ -29,7 +29,7 @@ from pygeodesy.utily import atan2, sincos2, fabs
|
|
|
29
29
|
from math import ceil as _ceil, floor as _floor, trunc as _trunc
|
|
30
30
|
|
|
31
31
|
__all__ = _ALL_LAZY.vector3dBase
|
|
32
|
-
__version__ = '25.
|
|
32
|
+
__version__ = '25.10.25'
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
@@ -112,9 +112,20 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
112
112
|
|
|
113
113
|
cmp = __cmp__
|
|
114
114
|
|
|
115
|
-
def __divmod__(self,
|
|
116
|
-
'''
|
|
117
|
-
|
|
115
|
+
def __divmod__(self, scalar): # PYCHOK no cover
|
|
116
|
+
'''Apply C{scalar} divmod to this vector's components.
|
|
117
|
+
|
|
118
|
+
@arg scalar: Divisor (C{scalar}).
|
|
119
|
+
|
|
120
|
+
@return: 2-Tuple C{(d, m)} each a L{Vector3d}.
|
|
121
|
+
'''
|
|
122
|
+
s = Scalar(divisor=scalar)
|
|
123
|
+
d, m = [], []
|
|
124
|
+
for x in self.xyz3:
|
|
125
|
+
q, r = divmod(x, s)
|
|
126
|
+
d.append(q)
|
|
127
|
+
m.append(r)
|
|
128
|
+
return self.classof(d), self.classof(m)
|
|
118
129
|
|
|
119
130
|
def __eq__(self, other):
|
|
120
131
|
'''Is this vector equal to an other vector?
|
|
@@ -132,15 +143,22 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
132
143
|
return _NotImplemented(self) # must return C{float}
|
|
133
144
|
|
|
134
145
|
def __floor__(self): # PYCHOK no cover
|
|
135
|
-
'''Return a vector with the C{floor} of
|
|
146
|
+
'''Return a vector with the C{floor} of each components.
|
|
136
147
|
|
|
137
148
|
@return: Floor-ed (L{Vector3d}).
|
|
138
149
|
'''
|
|
139
150
|
return self._mapped(_floor)
|
|
140
151
|
|
|
141
|
-
def __floordiv__(self,
|
|
142
|
-
'''
|
|
143
|
-
|
|
152
|
+
def __floordiv__(self, scalar): # PYCHOK no cover
|
|
153
|
+
'''Floor-divide this vector by a scalar, C{this // B{scalar}}.
|
|
154
|
+
|
|
155
|
+
@arg scalar: The divisor (C{scalar}).
|
|
156
|
+
|
|
157
|
+
@return: Floored quotient (L{Vector3d}).
|
|
158
|
+
|
|
159
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
160
|
+
'''
|
|
161
|
+
return self.floorDividedBy(scalar)
|
|
144
162
|
|
|
145
163
|
def __ge__(self, other):
|
|
146
164
|
'''Is this vector longer than or equal to an other vector?
|
|
@@ -183,9 +201,14 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
183
201
|
'''
|
|
184
202
|
return self._xyz(self.plus(other))
|
|
185
203
|
|
|
186
|
-
def __ifloordiv__(self,
|
|
187
|
-
'''
|
|
188
|
-
|
|
204
|
+
def __ifloordiv__(self, scalar): # PYCHOK no cover
|
|
205
|
+
'''Floor-divide this vector by a scalar I{in-place}, C{this //= B{scalar}}.
|
|
206
|
+
|
|
207
|
+
@arg scalar: The divisor (C{scalar}).
|
|
208
|
+
|
|
209
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
210
|
+
'''
|
|
211
|
+
return self._xyz(self.floorDividedBy(scalar))
|
|
189
212
|
|
|
190
213
|
def __imatmul__(self, other): # PYCHOK Python 3.5+
|
|
191
214
|
'''Cross multiply this and an other vector I{in-place}, C{this @= B{other}}.
|
|
@@ -215,9 +238,16 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
215
238
|
'''Not implemented, see method C{ints}.'''
|
|
216
239
|
return _NotImplemented(self) # must return C{int}
|
|
217
240
|
|
|
218
|
-
def __ipow__(self,
|
|
219
|
-
'''
|
|
220
|
-
|
|
241
|
+
def __ipow__(self, scalar, *mod): # PYCHOK no cover
|
|
242
|
+
'''Raise each component I{in-place} as C{pow(C, B{scalar})}.
|
|
243
|
+
|
|
244
|
+
@arg scalar: Exponent (C{scalar}).
|
|
245
|
+
|
|
246
|
+
@return: Power (L{Vector3d}).
|
|
247
|
+
|
|
248
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
249
|
+
'''
|
|
250
|
+
return self._xyz(self.pow(scalar, *mod))
|
|
221
251
|
|
|
222
252
|
def __isub__(self, other):
|
|
223
253
|
'''Subtract an other vector from this one I{in-place}, C{this -= B{other}}.
|
|
@@ -280,9 +310,19 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
280
310
|
'''
|
|
281
311
|
return self.cross(other)
|
|
282
312
|
|
|
283
|
-
def __mod__(self,
|
|
284
|
-
'''
|
|
285
|
-
|
|
313
|
+
def __mod__(self, modulus): # PYCHOK no cover
|
|
314
|
+
'''Apply C{scalar} modulo to this vector's components.
|
|
315
|
+
|
|
316
|
+
@arg modulus: Modulus (C{scalar}).
|
|
317
|
+
|
|
318
|
+
@return: Modulo (L{Vector3d}).
|
|
319
|
+
'''
|
|
320
|
+
m = Scalar(modulus=modulus)
|
|
321
|
+
|
|
322
|
+
def _mod(x):
|
|
323
|
+
return x % m
|
|
324
|
+
|
|
325
|
+
return self._mapped(_mod)
|
|
286
326
|
|
|
287
327
|
def __mul__(self, scalar):
|
|
288
328
|
'''Multiply this vector by a scalar, C{this * B{scalar}}.
|
|
@@ -318,13 +358,29 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
318
358
|
'''
|
|
319
359
|
return self if _pos_self else self.copy()
|
|
320
360
|
|
|
321
|
-
def __pow__(self,
|
|
322
|
-
'''
|
|
323
|
-
|
|
361
|
+
def __pow__(self, scalar, *mod): # PYCHOK no cover
|
|
362
|
+
'''Return a vector with components as C{pow(C, B{scalar})}.
|
|
363
|
+
|
|
364
|
+
@arg scalar: Exponent (C{scalar}).
|
|
365
|
+
|
|
366
|
+
@return: Power (L{Vector3d}).
|
|
367
|
+
|
|
368
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
369
|
+
'''
|
|
370
|
+
return self.pow(scalar, *mod)
|
|
324
371
|
|
|
325
|
-
__radd__
|
|
372
|
+
def __radd__(self, other): # PYCHOK no cover
|
|
373
|
+
'''Add this vector to an other vector, C{B{other} + this}.
|
|
374
|
+
|
|
375
|
+
@arg other: The other vector (L{Vector3d}).
|
|
376
|
+
|
|
377
|
+
@return: Sum (L{Vector3d}).
|
|
378
|
+
|
|
379
|
+
@raise TypeError: Incompatible B{C{other}} C{type}.
|
|
380
|
+
'''
|
|
381
|
+
return self.others(other).plus(self)
|
|
326
382
|
|
|
327
|
-
def __rdivmod__
|
|
383
|
+
def __rdivmod__(self, other):
|
|
328
384
|
'''Not implemented.'''
|
|
329
385
|
return _NotImplemented(self, other)
|
|
330
386
|
|
|
@@ -333,7 +389,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
333
389
|
# '''
|
|
334
390
|
# return self.toRepr()
|
|
335
391
|
|
|
336
|
-
def __rfloordiv__(self, other):
|
|
392
|
+
def __rfloordiv__(self, other):
|
|
337
393
|
'''Not implemented.'''
|
|
338
394
|
return _NotImplemented(self, other)
|
|
339
395
|
|
|
@@ -348,11 +404,11 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
348
404
|
'''
|
|
349
405
|
return self.others(other).cross(self)
|
|
350
406
|
|
|
351
|
-
def __rmod__(self, other):
|
|
407
|
+
def __rmod__(self, other):
|
|
352
408
|
'''Not implemented.'''
|
|
353
409
|
return _NotImplemented(self, other)
|
|
354
410
|
|
|
355
|
-
__rmul__ = __mul__
|
|
411
|
+
__rmul__ = __mul__ # scalar other
|
|
356
412
|
|
|
357
413
|
def __round__(self, *ndigits): # PYCHOK no cover
|
|
358
414
|
'''Return a vector with these components C{rounded}.
|
|
@@ -361,8 +417,11 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
361
417
|
|
|
362
418
|
@return: Rounded (L{Vector3d}).
|
|
363
419
|
'''
|
|
420
|
+
def _rnd(x):
|
|
421
|
+
return round(x, *ndigits)
|
|
422
|
+
|
|
364
423
|
# <https://docs.Python.org/3.12/reference/datamodel.html?#object.__round__>
|
|
365
|
-
return self.
|
|
424
|
+
return self._mapped(_rnd)
|
|
366
425
|
|
|
367
426
|
def __rpow__(self, other, *mod): # PYCHOK no cover
|
|
368
427
|
'''Not implemented.'''
|
|
@@ -379,9 +438,9 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
379
438
|
'''
|
|
380
439
|
return self.others(other).minus(self)
|
|
381
440
|
|
|
382
|
-
def __rtruediv__(self,
|
|
441
|
+
def __rtruediv__(self, other):
|
|
383
442
|
'''Not implemented.'''
|
|
384
|
-
return _NotImplemented(self,
|
|
443
|
+
return _NotImplemented(self, other)
|
|
385
444
|
|
|
386
445
|
# def __str__(self):
|
|
387
446
|
# '''Return the default C{str(self)}.
|
|
@@ -527,22 +586,39 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
527
586
|
'''
|
|
528
587
|
self._crosserrors = bool(raiser)
|
|
529
588
|
|
|
530
|
-
def dividedBy(self,
|
|
589
|
+
def dividedBy(self, scalar):
|
|
531
590
|
'''Divide this vector by a scalar.
|
|
532
591
|
|
|
533
|
-
@arg
|
|
592
|
+
@arg scalar: The divisor (C{scalar}).
|
|
534
593
|
|
|
535
594
|
@return: New, scaled vector (L{Vector3d}).
|
|
536
595
|
|
|
537
|
-
@raise TypeError: Non-scalar B{C{
|
|
596
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
538
597
|
|
|
539
|
-
@raise VectorError: Invalid or zero B{C{
|
|
598
|
+
@raise VectorError: Invalid or zero B{C{scalar}}.
|
|
540
599
|
'''
|
|
541
|
-
d = Scalar(divisor=
|
|
600
|
+
d = Scalar(divisor=scalar)
|
|
542
601
|
try:
|
|
543
602
|
return self._times(_1_0 / d)
|
|
544
603
|
except (ValueError, ZeroDivisionError) as x:
|
|
545
|
-
raise VectorError(divisor=
|
|
604
|
+
raise VectorError(divisor=scalar, cause=x)
|
|
605
|
+
|
|
606
|
+
def dividedBy_(self, scalar_x, *y_z):
|
|
607
|
+
'''Divide this vector by separate X, Y and Z divisors.
|
|
608
|
+
|
|
609
|
+
@arg scalar_x: X divisor (C{scalar}) or a vector's
|
|
610
|
+
X, Y, and Z components as divisors
|
|
611
|
+
(C{Cartesian}, L{Ecef9Tuple}, C{Nvector},
|
|
612
|
+
L{Vector3d}, L{Vector3Tuple}, L{Vector4Tuple}).
|
|
613
|
+
@arg y_z: Y and Z divisors (C{scalar}, C{scalar}), ignored
|
|
614
|
+
if B{C{scalar_x}} is not C{scalar}.
|
|
615
|
+
|
|
616
|
+
@return: New, scaled vector (L{Vector3d}).
|
|
617
|
+
|
|
618
|
+
@raise VectorError: Invalid B{C{scalar_x}} or B{C{y_z}}.
|
|
619
|
+
'''
|
|
620
|
+
x, y, z = _xyz3(self.dividedBy_, scalar_x, *y_z)
|
|
621
|
+
return self.classof(self.x / x, self.y / y, self.z / z)
|
|
546
622
|
|
|
547
623
|
def dot(self, other):
|
|
548
624
|
'''Compute the dot (scalar) product of this and an other vector.
|
|
@@ -595,6 +671,43 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
595
671
|
'''
|
|
596
672
|
return self._mapped(_float0)
|
|
597
673
|
|
|
674
|
+
def floorDividedBy(self, scalar):
|
|
675
|
+
'''Floor-divide this vector by a scalar.
|
|
676
|
+
|
|
677
|
+
@arg scalar: The divisor (C{scalar}).
|
|
678
|
+
|
|
679
|
+
@return: New, scaled vector (L{Vector3d}).
|
|
680
|
+
|
|
681
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
682
|
+
|
|
683
|
+
@raise VectorError: Invalid or zero B{C{scalar}}.
|
|
684
|
+
'''
|
|
685
|
+
d = Scalar(divisor=scalar)
|
|
686
|
+
try:
|
|
687
|
+
def _floor_d(x):
|
|
688
|
+
return x // d
|
|
689
|
+
|
|
690
|
+
return self._mapped(_floor_d)
|
|
691
|
+
except (ValueError, ZeroDivisionError) as x:
|
|
692
|
+
raise VectorError(divisor=scalar, cause=x)
|
|
693
|
+
|
|
694
|
+
def floorDividedBy_(self, scalar_x, *y_z):
|
|
695
|
+
'''Floor-divide this vector by separate X, Y and Z divisors.
|
|
696
|
+
|
|
697
|
+
@arg scalar_x: X divisor (C{scalar}) or a vector's
|
|
698
|
+
X, Y, and Z components as divisors
|
|
699
|
+
(C{Cartesian}, L{Ecef9Tuple}, C{Nvector},
|
|
700
|
+
L{Vector3d}, L{Vector3Tuple}, L{Vector4Tuple}).
|
|
701
|
+
@arg y_z: Y and Z divisors (C{scalar}, C{scalar}), ignored
|
|
702
|
+
if B{C{scalar_x}} is not C{scalar}.
|
|
703
|
+
|
|
704
|
+
@return: New, scaled vector (L{Vector3d}).
|
|
705
|
+
|
|
706
|
+
@raise VectorError: Invalid B{C{scalar_x}} or B{C{y_z}}.
|
|
707
|
+
'''
|
|
708
|
+
x, y, z = _xyz3(self.floorDividedBy_, scalar_x, *y_z)
|
|
709
|
+
return self.classof(self.x // x, self.y // y, self.z // z)
|
|
710
|
+
|
|
598
711
|
@Property
|
|
599
712
|
def _fromll(self):
|
|
600
713
|
'''(INTERNAL) Get the latlon reference (C{LatLon}) or C{None}.
|
|
@@ -617,11 +730,8 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
617
730
|
y = y / z
|
|
618
731
|
# z = _1_0
|
|
619
732
|
else:
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
y = -y
|
|
623
|
-
x = _copysignINF(x)
|
|
624
|
-
y = _copysignINF(y)
|
|
733
|
+
x = _copysignINF(_flipsign(x, z))
|
|
734
|
+
y = _copysignINF(_flipsign(y, z))
|
|
625
735
|
# z = NAN
|
|
626
736
|
return self.classof(x, y, _1_0)
|
|
627
737
|
|
|
@@ -705,7 +815,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
705
815
|
|
|
706
816
|
@see: Properties L{length2} and L{euclid}.
|
|
707
817
|
'''
|
|
708
|
-
return Float(length=hypot_(self.
|
|
818
|
+
return Float(length=hypot_(*self.xyz3))
|
|
709
819
|
|
|
710
820
|
@Property_RO
|
|
711
821
|
def length2(self): # __dict__ value overwritten by Property_RO C{_united}
|
|
@@ -713,7 +823,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
713
823
|
|
|
714
824
|
@see: Property L{length} and method C{equirectangular}.
|
|
715
825
|
'''
|
|
716
|
-
return Float(length2=hypot2_(self.
|
|
826
|
+
return Float(length2=hypot2_(*self.xyz3))
|
|
717
827
|
|
|
718
828
|
def _mapped(self, func):
|
|
719
829
|
'''(INTERNAL) Apply C{func} to all components.
|
|
@@ -815,12 +925,28 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
815
925
|
@arg y_z: Y and Z components (C{scalar}, C{scalar}),
|
|
816
926
|
ignored if B{C{other_x}} is not C{scalar}.
|
|
817
927
|
|
|
818
|
-
@return: New,
|
|
928
|
+
@return: New, vectorial vector (L{Vector3d}).
|
|
819
929
|
|
|
820
930
|
@raise ValueError: Invalid B{C{other_x}} or B{C{y_z}}.
|
|
821
931
|
'''
|
|
822
932
|
return self._plus(*_xyz3(self.plus_, other_x, *y_z))
|
|
823
933
|
|
|
934
|
+
def pow(self, scalar, *mod):
|
|
935
|
+
'''Raise each X, Y and Z to C{scalar} power.
|
|
936
|
+
|
|
937
|
+
@arg scalar: Exponent (C{scalar}).
|
|
938
|
+
|
|
939
|
+
@return: Power (L{Vector3d}).
|
|
940
|
+
|
|
941
|
+
@raise TypeError: Non-scalar B{C{scalar}}.
|
|
942
|
+
'''
|
|
943
|
+
p = Scalar(power=scalar)
|
|
944
|
+
|
|
945
|
+
def _pow(x):
|
|
946
|
+
return pow(x, p, *mod)
|
|
947
|
+
|
|
948
|
+
return self._mapped(_pow)
|
|
949
|
+
|
|
824
950
|
def rotate(self, axis, theta, fma=False):
|
|
825
951
|
'''Rotate this vector around an axis by a specified angle.
|
|
826
952
|
|
|
@@ -863,6 +989,16 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
863
989
|
'''DEPRECATED, use method C{rotate}.'''
|
|
864
990
|
return self.rotate(axis, theta) # PYCHOK no cover
|
|
865
991
|
|
|
992
|
+
def _roty(self, *pos, **name):
|
|
993
|
+
'''(INTERNAL) Prolate rotation, for C{+1 if pos else -1}.
|
|
994
|
+
'''
|
|
995
|
+
v = self.copy(**name)
|
|
996
|
+
if pos:
|
|
997
|
+
x, _, z = v.xyz3
|
|
998
|
+
_update_all(v, needed=3)
|
|
999
|
+
v._x, v._z = (-z, x) if pos[0] else (z, -x)
|
|
1000
|
+
return v
|
|
1001
|
+
|
|
866
1002
|
def times(self, factor):
|
|
867
1003
|
'''Multiply this vector by a scalar.
|
|
868
1004
|
|
|
@@ -989,8 +1125,10 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
989
1125
|
def _xyz(self, x_xyz, *y_z):
|
|
990
1126
|
'''(INTERNAL) Set the C{_x}, C{_y} and C{_z} attributes.
|
|
991
1127
|
'''
|
|
992
|
-
|
|
993
|
-
|
|
1128
|
+
xyz = _xyz3(_xyz_, x_xyz, *y_z)
|
|
1129
|
+
if self.xyz3 != xyz:
|
|
1130
|
+
_update_all(self, needed=3)
|
|
1131
|
+
self._x, self._y, self._z = xyz
|
|
994
1132
|
return self
|
|
995
1133
|
|
|
996
1134
|
@property_RO
|
|
@@ -999,9 +1137,15 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
999
1137
|
'''
|
|
1000
1138
|
return self.x, self.y, self.z
|
|
1001
1139
|
|
|
1002
|
-
@
|
|
1140
|
+
@Property_RO
|
|
1003
1141
|
def x2y2z2(self):
|
|
1004
|
-
'''Get the X, Y and Z components I{squared} (
|
|
1142
|
+
'''Get the X, Y and Z components, I{squared} (L{Vector3Tuple}).
|
|
1143
|
+
'''
|
|
1144
|
+
return _MODS.namedTuples.Vector3Tuple(*self.x2y2z23, name=self.name)
|
|
1145
|
+
|
|
1146
|
+
@property_RO
|
|
1147
|
+
def x2y2z23(self):
|
|
1148
|
+
'''Get the X, Y and Z components, I{squared} (3-tuple C{(x**2, y**2, z**2)}).
|
|
1005
1149
|
'''
|
|
1006
1150
|
return self.x**2, self.y**2, self.z**2
|
|
1007
1151
|
|
|
@@ -1037,7 +1181,7 @@ class Vector3dBase(_NamedBase): # sync __methods__ with .fsums.Fsum
|
|
|
1037
1181
|
|
|
1038
1182
|
|
|
1039
1183
|
def _xyz3(where, x_xyz, *y_z): # in .cartesianBase._rtp3
|
|
1040
|
-
'''(INTERNAL) Get , Y and Z as 3-tuple C{(x, y, z)}.
|
|
1184
|
+
'''(INTERNAL) Get X, Y and Z as 3-tuple C{(x, y, z)}.
|
|
1041
1185
|
'''
|
|
1042
1186
|
try:
|
|
1043
1187
|
xyz3 = map1(_float0, x_xyz, *y_z) if y_z else ( # islistuple for Vector*Tuple
|
|
@@ -1052,7 +1196,7 @@ __all__ += _ALL_DOCS(Vector3dBase)
|
|
|
1052
1196
|
|
|
1053
1197
|
# **) MIT License
|
|
1054
1198
|
#
|
|
1055
|
-
# Copyright (C) 2016-
|
|
1199
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
1056
1200
|
#
|
|
1057
1201
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
1058
1202
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/webmercator.py
CHANGED
|
@@ -353,7 +353,7 @@ def toWm(latlon, lon=None, earth=R_MA, Wm=Wm, **name_Wm_kwds_radius):
|
|
|
353
353
|
|
|
354
354
|
# **) MIT License
|
|
355
355
|
#
|
|
356
|
-
# Copyright (C) 2016-
|
|
356
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
357
357
|
#
|
|
358
358
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
359
359
|
# copy of this software and associated documentation files (the "Software"),
|
pygeodesy/wgrs.py
CHANGED
|
@@ -425,7 +425,7 @@ __all__ += _ALL_DOCS(decode3, decode5, # functions
|
|
|
425
425
|
|
|
426
426
|
# **) MIT License
|
|
427
427
|
#
|
|
428
|
-
# Copyright (C) 2016-
|
|
428
|
+
# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
429
429
|
#
|
|
430
430
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
431
431
|
# copy of this software and associated documentation files (the "Software"),
|