pygeodesy 25.4.8__py2.py3-none-any.whl → 25.5.5__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 +36 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +9 -9
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +8 -6
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +5 -3
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +32 -18
- pygeodesy/booleans.py +18 -16
- pygeodesy/cartesianBase.py +26 -24
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +22 -29
- pygeodesy/ecefLocals.py +186 -0
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +186 -164
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +7 -7
- pygeodesy/fmath.py +30 -14
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +79 -78
- pygeodesy/gars.py +4 -3
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +11 -9
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +5 -5
- pygeodesy/geoids.py +34 -31
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +28 -44
- pygeodesy/interns.py +10 -7
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +68 -62
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +20 -21
- pygeodesy/lazily.py +104 -78
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +56 -58
- pygeodesy/ltpTuples.py +35 -36
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +48 -177
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +83 -80
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +7 -7
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +110 -18
- pygeodesy/vector2d.py +20 -13
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/METADATA +30 -25
- pygeodesy-25.5.5.dist-info/RECORD +119 -0
- pygeodesy-25.4.8.dist-info/RECORD +0 -118
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/WHEEL +0 -0
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/top_level.txt +0 -0
pygeodesy/ellipsoids.py
CHANGED
|
@@ -64,18 +64,20 @@ Following is the list of predefined L{Ellipsoid}s, all instantiated lazily.
|
|
|
64
64
|
# make sure int/int division yields float quotient, see .basics
|
|
65
65
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
66
66
|
|
|
67
|
-
from pygeodesy.
|
|
67
|
+
# from pygeodesy.albers import AlbersEqualAreaCylindrical # _MODS
|
|
68
|
+
from pygeodesy.basics import copysign0, isbool, _isin, isint, typename
|
|
68
69
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS1, INF, NINF, PI4, PI_2, PI_3, R_M, R_MA, R_FM, \
|
|
69
|
-
_EPSqrt, _EPStol as _TOL, _floatuple as _T, _isfinite, \
|
|
70
|
+
_EPSqrt, _EPStol as _TOL, _floatuple as _T, _isfinite, _over, \
|
|
70
71
|
_0_0s, _0_0, _0_5, _1_0, _1_EPS, _2_0, _4_0, _90_0, \
|
|
71
72
|
_0_25, _3_0 # PYCHOK used!
|
|
72
73
|
from pygeodesy.errors import _AssertionError, IntersectionError, _ValueError, _xattr, _xkwds_not
|
|
73
74
|
from pygeodesy.fmath import cbrt, cbrt2, fdot, Fhorner, fpowers, hypot, hypot_, \
|
|
74
75
|
hypot1, hypot2, sqrt3, Fsum
|
|
75
76
|
# from pygeodesy.fsums import Fsum # from .fmath
|
|
77
|
+
# from pygeodesy.internals import typename # from .basics
|
|
76
78
|
from pygeodesy.interns import NN, _a_, _Airy1830_, _AiryModified_, _b_, _Bessel1841_, _beta_, \
|
|
77
|
-
_Clarke1866_, _Clarke1880IGN_, _DOT_, _f_, _GRS80_,
|
|
78
|
-
_Intl1924_, _incompatible_, _invalid_, _Krassovski1940_, \
|
|
79
|
+
_Clarke1866_, _Clarke1880IGN_, _DMAIN_, _DOT_, _f_, _GRS80_, \
|
|
80
|
+
_height_, _Intl1924_, _incompatible_, _invalid_, _Krassovski1940_, \
|
|
79
81
|
_Krassowsky1940_, _lat_, _meridional_, _negative_, _not_finite_, \
|
|
80
82
|
_prime_vertical_, _radius_, _Sphere_, _SPACE_, _vs_, _WGS72_, _WGS84_
|
|
81
83
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
|
|
@@ -86,25 +88,25 @@ from pygeodesy.props import deprecated_Property_RO, Property_RO, property_doc_,
|
|
|
86
88
|
deprecated_property_RO, property_RO, property_ROver
|
|
87
89
|
from pygeodesy.streprs import Fmt, fstr, instr, strs, unstr
|
|
88
90
|
# from pygeodesy.triaxials import _hartzell3 # _MODS
|
|
89
|
-
from pygeodesy.units import
|
|
90
|
-
Meter2, Meter3, Phi, Phid, Radius, Radius_, Scalar
|
|
91
|
+
from pygeodesy.units import Azimuth, Bearing, Distance, Float, Float_, Height, Lamd, Lat, \
|
|
92
|
+
Meter, Meter2, Meter3, Phi, Phid, Radius, Radius_, Scalar
|
|
91
93
|
from pygeodesy.utily import atan1, atan1d, atan2b, degrees90, m2radians, radians2m, sincos2d
|
|
92
94
|
|
|
93
95
|
from math import asinh, atan, atanh, cos, degrees, exp, fabs, radians, sin, sinh, sqrt, tan # as _tan
|
|
94
96
|
|
|
95
97
|
__all__ = _ALL_LAZY.ellipsoids
|
|
96
|
-
__version__ = '
|
|
98
|
+
__version__ = '25.04.28'
|
|
97
99
|
|
|
98
100
|
_f_0_0 = Float(f =_0_0) # zero flattening
|
|
99
101
|
_f__0_0 = Float(f_=_0_0) # zero inverse flattening
|
|
100
102
|
# see U{WGS84_f<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Constants.html>}
|
|
101
|
-
_f__WGS84 = Float(f_=_1_0 / (1000000000 / 298257223563)) # 298.
|
|
103
|
+
_f__WGS84 = Float(f_=_1_0 / (1000000000 / 298257223563)) # 298.257223562_999_97 vs 298.257223563
|
|
102
104
|
|
|
103
105
|
|
|
104
106
|
def _aux(lat, inverse, auxLat, clip=90):
|
|
105
107
|
'''Return a named auxiliary latitude in C{degrees}.
|
|
106
108
|
'''
|
|
107
|
-
return Lat(lat, clip=clip, name=_lat_ if inverse else auxLat
|
|
109
|
+
return Lat(lat, clip=clip, name=_lat_ if inverse else typename(auxLat))
|
|
108
110
|
|
|
109
111
|
|
|
110
112
|
def _s2_c2(phi):
|
|
@@ -138,12 +140,14 @@ class a_f2Tuple(_NamedTuple):
|
|
|
138
140
|
@arg f: Flattening (C{scalar} < 1, negative for I{prolate}).
|
|
139
141
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
140
142
|
|
|
141
|
-
@return: An L{a_f2Tuple}C{(a, f)}
|
|
143
|
+
@return: An L{a_f2Tuple}C{(a, f)}.
|
|
142
144
|
|
|
143
145
|
@raise UnitError: Invalid B{C{a}} or B{C{f}}.
|
|
144
146
|
|
|
145
|
-
@note: C{abs(B{f}) < EPS} is
|
|
146
|
-
|
|
147
|
+
@note: C{abs(B{f}) < }L{EPS<pygeodesy.constants.EPS>} is
|
|
148
|
+
forced to C{B{f}=0}, I{spherical}.
|
|
149
|
+
|
|
150
|
+
@note: Negative C{B{f}} produces a I{prolate} ellipsoid.
|
|
147
151
|
'''
|
|
148
152
|
a = Radius_(a=a) # low=EPS, high=None
|
|
149
153
|
f = Float_( f=f, low=None, high=EPS1)
|
|
@@ -243,7 +247,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
243
247
|
if not _isfinite(a):
|
|
244
248
|
raise ValueError(_SPACE_(_a_, _not_finite_))
|
|
245
249
|
|
|
246
|
-
if b: # not
|
|
250
|
+
if b: # not _isin(b, None, _0_0)
|
|
247
251
|
b = Radius_(b=b) # low=EPS
|
|
248
252
|
f = a_b2f(a, b) if f is None else Float(f=f)
|
|
249
253
|
f_ = f2f_(f) if f_ is None else Float(f_=f_)
|
|
@@ -357,11 +361,16 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
357
361
|
'''
|
|
358
362
|
return a_f2Tuple(self.a, self.f, name=self.name)
|
|
359
363
|
|
|
364
|
+
a_f2 = a_f # synonym
|
|
365
|
+
|
|
360
366
|
@Property_RO
|
|
361
367
|
def A(self):
|
|
362
368
|
'''Get the UTM I{meridional (or rectifying)} radius (C{meter}).
|
|
363
369
|
|
|
364
|
-
@
|
|
370
|
+
@note: C{A * PI / 2} ≈= L{L<Ellipsoid.L>}, the I{quarter meridian}.
|
|
371
|
+
|
|
372
|
+
@see: I{Meridian arc unit} U{Q<https://StudyLib.net/doc/7443565/>},
|
|
373
|
+
the mean, meridional length I{per radian}.
|
|
365
374
|
'''
|
|
366
375
|
A, n = self.a, self.n
|
|
367
376
|
if n:
|
|
@@ -373,6 +382,11 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
373
382
|
# A *= fhorner(n**2, 1048576, 262144, 16384, 4096, 1600, 784, 441) / 1048576) / (1 + n)
|
|
374
383
|
A = Radius(A=Fhorner(n**2, 1048576, 262144, 16384, 4096, 1600, 784, 441).fover(d))
|
|
375
384
|
return A
|
|
385
|
+
# # Moritz, H. <https://Geodesy.Geology.Ohio-State.EDU/course/refpapers/00740128.pdf>
|
|
386
|
+
# # q = 4 / self.rocPolar
|
|
387
|
+
# # Q = (1 - 3 / 4 * e'2 + 45 / 64 * e'4 - 175 / 256 * e'6 + 11025 / 16384 * e'8) * rocPolar
|
|
388
|
+
# # = (4 + e'2 * (-3 + e'2 * (45 / 16 + e'2 * (-175 / 64 + e'2 * 11025 / 4096)))) / q
|
|
389
|
+
# return Radius(Q=Fhorner(self.e22, 4, -3, 45 / 16, -175 / 64, 11025 / 4096).fover(q))
|
|
376
390
|
|
|
377
391
|
@Property_RO
|
|
378
392
|
def _albersCyl(self):
|
|
@@ -424,7 +438,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
424
438
|
t = Fmt.EQUAL(self._DOT_(n), t)
|
|
425
439
|
raise Error(t, txt=txt or Fmt.exceeds_eps(eps))
|
|
426
440
|
return Float(v if self.f else f0, name=n)
|
|
427
|
-
raise Error(unstr(self._DOT_(self._assert
|
|
441
|
+
raise Error(unstr(self._DOT_(typename(self._assert)), val,
|
|
428
442
|
eps=eps, f0=f0, **name_value))
|
|
429
443
|
|
|
430
444
|
def auxAuthalic(self, lat, inverse=False):
|
|
@@ -442,7 +456,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
442
456
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, p 16.
|
|
443
457
|
'''
|
|
444
458
|
if self.f:
|
|
445
|
-
f
|
|
459
|
+
f = self._albersCyl._tanf if inverse else \
|
|
460
|
+
self._albersCyl._txif # PYCHOK attr
|
|
446
461
|
lat = atan1d(f(tan(Phid(lat)))) # PYCHOK attr
|
|
447
462
|
return _aux(lat, inverse, Ellipsoid.auxAuthalic)
|
|
448
463
|
|
|
@@ -461,7 +476,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
461
476
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 15-16.
|
|
462
477
|
'''
|
|
463
478
|
if self.f:
|
|
464
|
-
f
|
|
479
|
+
f = self.es_tauf if inverse else self.es_taupf # PYCHOK attr
|
|
465
480
|
lat = atan1d(f(tan(Phid(lat)))) # PYCHOK attr
|
|
466
481
|
return _aux(lat, inverse, Ellipsoid.auxConformal)
|
|
467
482
|
|
|
@@ -480,8 +495,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
480
495
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 17-18.
|
|
481
496
|
'''
|
|
482
497
|
if self.f:
|
|
483
|
-
f
|
|
484
|
-
lat = atan1d(
|
|
498
|
+
f = self.a2_b2 if inverse else self.b2_a2
|
|
499
|
+
lat = atan1d(tan(Phid(lat)) * f)
|
|
485
500
|
return _aux(lat, inverse, Ellipsoid.auxGeocentric)
|
|
486
501
|
|
|
487
502
|
def auxIsometric(self, lat, inverse=False):
|
|
@@ -503,7 +518,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
503
518
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 15-16.
|
|
504
519
|
'''
|
|
505
520
|
if self.f:
|
|
506
|
-
r
|
|
521
|
+
r = Phid(lat, clip=0)
|
|
507
522
|
lat = degrees(atan1(self.es_tauf(sinh(r))) if inverse else
|
|
508
523
|
asinh(self.es_taupf(tan(r))))
|
|
509
524
|
# clip=0, since auxIsometric(+/-90) is far outside [-90..+90]
|
|
@@ -549,9 +564,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
549
564
|
if inverse:
|
|
550
565
|
e = self._elliptic_e22
|
|
551
566
|
d = degrees90(e.fEinv(e.cE * lat / _90_0))
|
|
552
|
-
lat =
|
|
567
|
+
lat = self.auxParametric(d, inverse=True)
|
|
553
568
|
else:
|
|
554
|
-
lat =
|
|
569
|
+
lat = _over(self.Llat(lat), self.L) * _90_0
|
|
555
570
|
return _aux(lat, inverse, Ellipsoid.auxRectifying)
|
|
556
571
|
|
|
557
572
|
@Property_RO
|
|
@@ -582,7 +597,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
582
597
|
|
|
583
598
|
@see: U{Radii of Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
584
599
|
'''
|
|
585
|
-
return Radius(b2_a=self.b2
|
|
600
|
+
return Radius(b2_a=_over(self.b2, self.a) if self.f else self.b)
|
|
586
601
|
|
|
587
602
|
@Property_RO
|
|
588
603
|
def b2_a2(self):
|
|
@@ -831,7 +846,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
831
846
|
def _elliptic_e12(self): # see I{Karney}'s Ellipsoid._e12
|
|
832
847
|
'''(INTERNAL) Elliptic helper for C{Rhumb}.
|
|
833
848
|
'''
|
|
834
|
-
e12 = self.e2
|
|
849
|
+
e12 = _over(self.e2, self.e2 - _1_0) # NOT DEPRECATED .e12!
|
|
835
850
|
return _MODS.elliptic.Elliptic(e12)
|
|
836
851
|
|
|
837
852
|
@Property_RO
|
|
@@ -869,7 +884,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
869
884
|
if r < 0:
|
|
870
885
|
raise ValueError(_negative_)
|
|
871
886
|
except (TypeError, ValueError) as x:
|
|
872
|
-
t = self._DOT_(Ellipsoid.e2s2
|
|
887
|
+
t = self._DOT_(typename(Ellipsoid.e2s2))
|
|
873
888
|
raise _ValueError(t, s, cause=x)
|
|
874
889
|
return r
|
|
875
890
|
|
|
@@ -919,8 +934,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
919
934
|
'''
|
|
920
935
|
t = Scalar(taup=taup)
|
|
921
936
|
if self.f: # .isEllipsoidal
|
|
922
|
-
a =
|
|
923
|
-
T =
|
|
937
|
+
a = fabs(t)
|
|
938
|
+
T = (self._exp_es_atanh_1 if a > 70 else self._1_e21) * t
|
|
924
939
|
if fabs(T * _EPSqrt) < _2_0: # handles +/- INF and NAN
|
|
925
940
|
s = (a * _TOL) if a > _1_0 else _TOL
|
|
926
941
|
for T, _, d in self._es_tauf3(t, T): # max 2
|
|
@@ -939,8 +954,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
939
954
|
_tf2 = self._es_taupf2
|
|
940
955
|
for i in range(1, N + 1):
|
|
941
956
|
a, h = _tf2(T)
|
|
942
|
-
d = (taup - a) * (e + T**2) / (hypot1(a) * h)
|
|
943
957
|
# = (taup - a) / hypot1(a) / ((e + T**2) / h)
|
|
958
|
+
d = _over((taup - a) * (T**2 + e), hypot1(a) * h)
|
|
944
959
|
T, d = _F2_(d) # τi, (τi - τi-1)
|
|
945
960
|
yield T, i, d
|
|
946
961
|
|
|
@@ -1085,8 +1100,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1085
1100
|
|
|
1086
1101
|
@arg pov: Point-Of-View outside this ellipsoid (C{Cartesian}, L{Ecef9Tuple}
|
|
1087
1102
|
or L{Vector3d}).
|
|
1088
|
-
@kwarg los: Line-Of-Sight, I{direction} to this ellipsoid (L{Vector3d})
|
|
1089
|
-
C{
|
|
1103
|
+
@kwarg los: Line-Of-Sight, I{direction} to this ellipsoid (L{Los}, L{Vector3d})
|
|
1104
|
+
or C{True} for the I{normal, perpendicular, plumb} to the surface
|
|
1105
|
+
of this ellipsoid or C{False} or C{None} to point to its center.
|
|
1090
1106
|
|
|
1091
1107
|
@return: L{Vector4Tuple}C{(x, y, z, h)} with the cartesian coordinates C{x},
|
|
1092
1108
|
C{y} and C{z} of the projection on or the intersection with this
|
|
@@ -1095,8 +1111,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1095
1111
|
|
|
1096
1112
|
@raise IntersectionError: Null B{C{pov}} or B{C{los}} vector, or B{C{pov}}
|
|
1097
1113
|
is inside this ellipsoid or B{C{los}} points
|
|
1098
|
-
outside this ellipsoid or
|
|
1099
|
-
direction.
|
|
1114
|
+
outside this ellipsoid or in opposite direction.
|
|
1100
1115
|
|
|
1101
1116
|
@raise TypeError: Invalid B{C{pov}} or B{C{los}}.
|
|
1102
1117
|
|
|
@@ -1105,10 +1120,10 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1105
1120
|
methods L{Ellipsoid.height4} and L{Triaxial.hartzell4}.
|
|
1106
1121
|
'''
|
|
1107
1122
|
try:
|
|
1108
|
-
v, d,
|
|
1123
|
+
v, d, i = _MODS.triaxials._hartzell3(pov, los, self._triaxial)
|
|
1109
1124
|
except Exception as x:
|
|
1110
1125
|
raise IntersectionError(pov=pov, los=los, cause=x)
|
|
1111
|
-
return Vector4Tuple(v.x, v.y, v.z, d, name__=self.hartzell4)
|
|
1126
|
+
return Vector4Tuple(v.x, v.y, v.z, d, iteration=i, name__=self.hartzell4)
|
|
1112
1127
|
|
|
1113
1128
|
@Property_RO
|
|
1114
1129
|
def _hash(self):
|
|
@@ -1164,10 +1179,10 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1164
1179
|
h = t.minus(v).length
|
|
1165
1180
|
|
|
1166
1181
|
else: # radial to ellipsoid's center
|
|
1167
|
-
h =
|
|
1182
|
+
h = hypot_(a * v.z, b * v.x, b * v.y)
|
|
1168
1183
|
t = (a * b / h) if h > EPS0 else _0_0 # EPS
|
|
1169
|
-
v =
|
|
1170
|
-
h =
|
|
1184
|
+
v = v.times(t)
|
|
1185
|
+
h = r * (_1_0 - t)
|
|
1171
1186
|
|
|
1172
1187
|
return Vector4Tuple(v.x, v.y, v.z, h, iteration=i, name__=self.height4)
|
|
1173
1188
|
|
|
@@ -1238,7 +1253,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1238
1253
|
|
|
1239
1254
|
@raise ValueError: Invalid B{C{order}}.
|
|
1240
1255
|
'''
|
|
1241
|
-
if not (isint(order) and order
|
|
1256
|
+
if not (isint(order) and _isin(order, 4, 6, 8)):
|
|
1242
1257
|
raise _ValueError(order=order)
|
|
1243
1258
|
if self._KsOrder != order:
|
|
1244
1259
|
Ellipsoid.AlphaKs._update(self)
|
|
@@ -1302,8 +1317,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1302
1317
|
return degrees(self.m2radians(distance, lat=lat))
|
|
1303
1318
|
|
|
1304
1319
|
def m2radians(self, distance, lat=0):
|
|
1305
|
-
'''Convert a distance to an angle along the equator or
|
|
1306
|
-
|
|
1320
|
+
'''Convert a distance to an angle along the equator or along
|
|
1321
|
+
a parallel of (geodetic) latitude.
|
|
1307
1322
|
|
|
1308
1323
|
@arg distance: Distance (C{meter}).
|
|
1309
1324
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
@@ -1336,23 +1351,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1336
1351
|
|
|
1337
1352
|
polaradius = b # Rpolar
|
|
1338
1353
|
|
|
1339
|
-
#
|
|
1340
|
-
# def Q(self):
|
|
1341
|
-
# '''Get the I{meridian arc unit} C{Q}, the mean, meridional length I{per radian} C({float}).
|
|
1342
|
-
#
|
|
1343
|
-
# @note: C{Q * PI / 2} ≈ C{L}, the I{quarter meridian}.
|
|
1344
|
-
#
|
|
1345
|
-
# @see: Property C{A} and U{Engsager, K., Poder, K.<https://StudyLib.net/doc/7443565/
|
|
1346
|
-
# a-highly-accurate-world-wide-algorithm-for-the-transverse...>}.
|
|
1347
|
-
# '''
|
|
1348
|
-
# n = self.n
|
|
1349
|
-
# d = (n + _1_0) / self.a
|
|
1350
|
-
# return Float(Q=Fhorner(n**2, _1_0, _0_25, _1_16th, _0_25).fover(d) if d else self.b)
|
|
1351
|
-
|
|
1352
|
-
# # Moritz, H. <https://Geodesy.Geology.Ohio-State.EDU/course/refpapers/00740128.pdf>
|
|
1353
|
-
# # Q = (1 - 3/4 * e'2 + 45/64 * e'4 - 175/256 * e'6 + 11025/16384 * e'8) * rocPolar
|
|
1354
|
-
# # = (4 + e'2 * (-3 + e'2 * (45/16 + e'2 * (-175/64 + e'2 * 11025/4096)))) * rocPolar / 4
|
|
1355
|
-
# return Fhorner(self.e22, 4, -3, 45 / 16, -175 / 64, 11025 / 4096).fover(4 / self.rocPolar)
|
|
1354
|
+
# Q = A # I{meridian arc unit} C{Q}, the mean, meridional length I{per radian}
|
|
1356
1355
|
|
|
1357
1356
|
@deprecated_Property_RO
|
|
1358
1357
|
def quarteradius(self): # PYCHOK no cover
|
|
@@ -1379,16 +1378,13 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1379
1378
|
<https://WikiPedia.org/wiki/Earth_radius>}.
|
|
1380
1379
|
'''
|
|
1381
1380
|
return Radius(R2=sqrt(self.c2) if self.f else self.a)
|
|
1382
|
-
|
|
1383
|
-
Rauthalic = R2
|
|
1384
|
-
|
|
1385
|
-
# @Property_RO
|
|
1386
|
-
# def R2(self):
|
|
1387
1381
|
# # Moritz, H. <https://Geodesy.Geology.Ohio-State.EDU/course/refpapers/00740128.pdf>
|
|
1388
1382
|
# # R2 = (1 - 2/3 * e'2 + 26/45 * e'4 - 100/189 * e'6 + 7034/14175 * e'8) * rocPolar
|
|
1389
1383
|
# # = (3 + e'2 * (-2 + e'2 * (26/15 + e'2 * (-100/63 + e'2 * 7034/4725)))) * rocPolar / 3
|
|
1390
1384
|
# return Fhorner(self.e22, 3, -2, 26 / 15, -100 / 63, 7034 / 4725).fover(3 / self.rocPolar)
|
|
1391
1385
|
|
|
1386
|
+
Rauthalic = R2
|
|
1387
|
+
|
|
1392
1388
|
@Property_RO
|
|
1393
1389
|
def R2x(self):
|
|
1394
1390
|
'''Get the I{authalic} earth radius (C{meter}), M{sqrt(c2x)}.
|
|
@@ -1646,19 +1642,26 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1646
1642
|
r = self.e2s2(sin(a))
|
|
1647
1643
|
if r > EPS02:
|
|
1648
1644
|
n = self.a / sqrt(r)
|
|
1649
|
-
m = n *
|
|
1645
|
+
m = n * self.e21 / r
|
|
1650
1646
|
else:
|
|
1651
1647
|
m = n = _0_0
|
|
1652
1648
|
else:
|
|
1653
1649
|
m = n = self.a
|
|
1654
1650
|
if scaled and a:
|
|
1655
1651
|
n *= cos(a) if a < PI_2 else _0_0
|
|
1656
|
-
return Curvature2Tuple(
|
|
1657
|
-
|
|
1652
|
+
return Curvature2Tuple(m, n)
|
|
1653
|
+
|
|
1654
|
+
def rocAzimuth(self, lat, azimuth):
|
|
1655
|
+
'''Compute the I{directional} radius of curvature of (geodetic) latitude
|
|
1656
|
+
and C{azimuth} compass direction.
|
|
1657
|
+
|
|
1658
|
+
@see: Method L{rocBearing<Ellipsoid.rocBearing>} for details, using C{azimuth} for C{bearing}.
|
|
1659
|
+
'''
|
|
1660
|
+
return Radius(rocAzimuth=self._rocDirectional(lat, Azimuth(azimuth)))
|
|
1658
1661
|
|
|
1659
1662
|
def rocBearing(self, lat, bearing):
|
|
1660
|
-
'''Compute the I{directional} radius of curvature of (geodetic)
|
|
1661
|
-
|
|
1663
|
+
'''Compute the I{directional} radius of curvature of (geodetic) latitude
|
|
1664
|
+
and C{bearing} compass direction.
|
|
1662
1665
|
|
|
1663
1666
|
@arg lat: Latitude (C{degrees90}).
|
|
1664
1667
|
@arg bearing: Direction (compass C{degrees360}).
|
|
@@ -1672,18 +1675,23 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1672
1675
|
|
|
1673
1676
|
@see: U{Radii of Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}
|
|
1674
1677
|
'''
|
|
1678
|
+
return Radius(rocBearing=self._rocDirectional(lat, Bearing(bearing)))
|
|
1679
|
+
|
|
1680
|
+
def _rocDirectional(self, lat, deg):
|
|
1681
|
+
'''(INTERNAL) Helper for C{rocAzimuth} and C{rocBearing}.
|
|
1682
|
+
'''
|
|
1675
1683
|
if self.f:
|
|
1676
|
-
s2, c2 = _s2_c2(
|
|
1684
|
+
s2, c2 = _s2_c2(radians(deg))
|
|
1677
1685
|
m, n = self.roc2_(Phid(lat))
|
|
1678
1686
|
if n < m: # == n / (c2 * n / m + s2)
|
|
1679
1687
|
c2 *= n / m
|
|
1680
1688
|
elif m < n: # == m / (c2 + s2 * m / n)
|
|
1681
1689
|
s2 *= m / n
|
|
1682
|
-
n
|
|
1683
|
-
|
|
1690
|
+
n = m
|
|
1691
|
+
r = _over(n, c2 + s2) # == 1 / (c2 / m + s2 / n)
|
|
1684
1692
|
else:
|
|
1685
|
-
|
|
1686
|
-
return
|
|
1693
|
+
r = self.b # == self.a
|
|
1694
|
+
return r
|
|
1687
1695
|
|
|
1688
1696
|
@Property_RO
|
|
1689
1697
|
def rocEquatorial2(self):
|
|
@@ -1694,8 +1702,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1694
1702
|
L{a2_b}, C{rocPolar} and polar and equatorial U{Radii of Curvature
|
|
1695
1703
|
<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
1696
1704
|
'''
|
|
1697
|
-
|
|
1698
|
-
|
|
1705
|
+
m = self.b2_a if self.f else self.a
|
|
1706
|
+
return Curvature2Tuple(m, self.a)
|
|
1699
1707
|
|
|
1700
1708
|
def rocGauss(self, lat):
|
|
1701
1709
|
'''Compute the I{Gaussian} radius of curvature of (geodetic) latitude.
|
|
@@ -1716,7 +1724,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1716
1724
|
g = self.b
|
|
1717
1725
|
if self.f:
|
|
1718
1726
|
s2, c2 = _s2_c2(Phid(lat))
|
|
1719
|
-
g = g
|
|
1727
|
+
g = _over(g, c2 + self.b2_a2 * s2)
|
|
1720
1728
|
return Radius(rocGauss=g)
|
|
1721
1729
|
|
|
1722
1730
|
def rocMean(self, lat):
|
|
@@ -1733,9 +1741,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1733
1741
|
'''
|
|
1734
1742
|
if self.f:
|
|
1735
1743
|
m, n = self.roc2_(Phid(lat))
|
|
1736
|
-
m *= n * _2_0
|
|
1744
|
+
m *= _over(n * _2_0, m + n) # == 2 / (1 / m + 1 / n)
|
|
1737
1745
|
else:
|
|
1738
|
-
m =
|
|
1746
|
+
m = self.a
|
|
1739
1747
|
return Radius(rocMean=m)
|
|
1740
1748
|
|
|
1741
1749
|
def rocMeridional(self, lat):
|
|
@@ -1751,8 +1759,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1751
1759
|
<https://www.EdWilliams.org/avform.htm#flat>} and U{Radii of
|
|
1752
1760
|
Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
1753
1761
|
'''
|
|
1754
|
-
|
|
1755
|
-
|
|
1762
|
+
r = self.roc2_(Phid(lat)) if lat else self.rocEquatorial2
|
|
1763
|
+
return Radius(rocMeridional=r.meridional)
|
|
1756
1764
|
|
|
1757
1765
|
rocPolar = a2_b # synonymous
|
|
1758
1766
|
|
|
@@ -1771,8 +1779,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1771
1779
|
U{Radii of Curvature<https://WikiPedia.org/wiki/
|
|
1772
1780
|
Earth_radius#Radii_of_curvature>}.
|
|
1773
1781
|
'''
|
|
1774
|
-
|
|
1775
|
-
|
|
1782
|
+
r = self.roc2_(Phid(lat)) if lat else self.rocEquatorial2
|
|
1783
|
+
return Radius(rocPrimeVertical=r.prime_vertical)
|
|
1776
1784
|
|
|
1777
1785
|
rocTransverse = rocPrimeVertical # synonymous
|
|
1778
1786
|
|
|
@@ -1792,7 +1800,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1792
1800
|
|
|
1793
1801
|
@see: U{Earth radius<https://WikiPedia.org/wiki/Earth_radius>}.
|
|
1794
1802
|
'''
|
|
1795
|
-
r =
|
|
1803
|
+
r = self.a
|
|
1804
|
+
if self.f:
|
|
1805
|
+
r *= cbrt2((sqrt3(self.b_a) + _1_0) * _0_5)
|
|
1796
1806
|
return Radius(Rrectifying=r)
|
|
1797
1807
|
|
|
1798
1808
|
@deprecated_Property_RO
|
|
@@ -1806,9 +1816,11 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1806
1816
|
|
|
1807
1817
|
@see: C{Rbiaxial}
|
|
1808
1818
|
'''
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1819
|
+
q, b = self.a, self.b
|
|
1820
|
+
if b < q:
|
|
1821
|
+
q *= sqrt((self.b2_a2 + _3_0) * _0_25)
|
|
1822
|
+
elif b > q:
|
|
1823
|
+
q = sqrt((self.a2_b2 * _3_0 + _1_0) * _0_25) * b
|
|
1812
1824
|
return Radius(Rtriaxial=q)
|
|
1813
1825
|
|
|
1814
1826
|
def toEllipsoid2(self, **name):
|
|
@@ -1897,22 +1909,23 @@ class Ellipsoid2(Ellipsoid):
|
|
|
1897
1909
|
Ellipsoid.__init__(self, a, f=f, **name)
|
|
1898
1910
|
|
|
1899
1911
|
|
|
1900
|
-
def
|
|
1912
|
+
def _ispherical_a_b(a, b):
|
|
1901
1913
|
'''(INTERNAL) C{True} for spherical or invalid C{a} or C{b}.
|
|
1902
1914
|
'''
|
|
1903
1915
|
return a < EPS0 or b < EPS0 or fabs(a - b) < EPS0
|
|
1904
1916
|
|
|
1905
1917
|
|
|
1906
|
-
def
|
|
1918
|
+
def _ispherical_f(f):
|
|
1907
1919
|
'''(INTERNAL) C{True} for spherical or invalid C{f}.
|
|
1908
1920
|
'''
|
|
1909
|
-
return
|
|
1921
|
+
return f > EPS1 or fabs(f) < EPS
|
|
1910
1922
|
|
|
1911
1923
|
|
|
1912
|
-
def
|
|
1924
|
+
def _ispherical_f_(f_):
|
|
1913
1925
|
'''(INTERNAL) C{True} for spherical or invalid C{f_}.
|
|
1914
1926
|
'''
|
|
1915
|
-
|
|
1927
|
+
f_ = fabs(f_)
|
|
1928
|
+
return f_ < EPS or f_ > _1_EPS
|
|
1916
1929
|
|
|
1917
1930
|
|
|
1918
1931
|
def a_b2e(a, b):
|
|
@@ -1921,12 +1934,12 @@ def a_b2e(a, b):
|
|
|
1921
1934
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1922
1935
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1923
1936
|
|
|
1924
|
-
@return: The I{unsigned}, (1st) eccentricity (C{float} or C{0}),
|
|
1925
|
-
M{sqrt(1 - (b / a)**2)}.
|
|
1937
|
+
@return: The I{unsigned}, (1st) eccentricity (C{float} or C{0}), M{sqrt(1 - (b / a)**2)}.
|
|
1926
1938
|
|
|
1927
1939
|
@note: The result is always I{non-negative} and C{0} for I{near-spherical} ellipsoids.
|
|
1928
1940
|
'''
|
|
1929
|
-
|
|
1941
|
+
e2 = _a2b2e2(a, b, b2=False)
|
|
1942
|
+
return Float(e=sqrt(fabs(e2)) if e2 else _0_0) # == sqrt(fabs((a - b) * (a + b))) / a
|
|
1930
1943
|
|
|
1931
1944
|
|
|
1932
1945
|
def a_b2e2(a, b):
|
|
@@ -1935,13 +1948,12 @@ def a_b2e2(a, b):
|
|
|
1935
1948
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1936
1949
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1937
1950
|
|
|
1938
|
-
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or C{0}),
|
|
1939
|
-
M{1 - (b / a)**2}.
|
|
1951
|
+
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or C{0}), M{1 - (b / a)**2}.
|
|
1940
1952
|
|
|
1941
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1942
|
-
|
|
1953
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1954
|
+
for I{near-spherical} ellipsoids.
|
|
1943
1955
|
'''
|
|
1944
|
-
return Float(e2=
|
|
1956
|
+
return Float(e2=_a2b2e2(a, b, b2=False))
|
|
1945
1957
|
|
|
1946
1958
|
|
|
1947
1959
|
def a_b2e22(a, b):
|
|
@@ -1950,13 +1962,12 @@ def a_b2e22(a, b):
|
|
|
1950
1962
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1951
1963
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1952
1964
|
|
|
1953
|
-
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} or C{0}),
|
|
1954
|
-
M{(a / b)**2 - 1}.
|
|
1965
|
+
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} or C{0}), M{(a / b)**2 - 1}.
|
|
1955
1966
|
|
|
1956
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1957
|
-
|
|
1967
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1968
|
+
for I{near-spherical} ellipsoids.
|
|
1958
1969
|
'''
|
|
1959
|
-
return Float(e22=
|
|
1970
|
+
return Float(e22=_a2b2e2(a, b, a2=False))
|
|
1960
1971
|
|
|
1961
1972
|
|
|
1962
1973
|
def a_b2e32(a, b):
|
|
@@ -1968,11 +1979,23 @@ def a_b2e32(a, b):
|
|
|
1968
1979
|
@return: The I{signed}, 3rd eccentricity I{squared} (C{float} or C{0}),
|
|
1969
1980
|
M{(a**2 - b**2) / (a**2 + b**2)}.
|
|
1970
1981
|
|
|
1971
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1972
|
-
|
|
1982
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1983
|
+
for I{near-spherical} ellipsoids.
|
|
1984
|
+
'''
|
|
1985
|
+
return Float(e32=_a2b2e2(a, b))
|
|
1986
|
+
|
|
1987
|
+
|
|
1988
|
+
def _a2b2e2(a, b, a2=True, b2=True):
|
|
1989
|
+
'''(INTERNAL) Helper for C{a_b2e}, C{a_b2e2}, C{a_b2e22} and C{a_b2e32}.
|
|
1973
1990
|
'''
|
|
1974
|
-
|
|
1975
|
-
|
|
1991
|
+
if _ispherical_a_b(a, b):
|
|
1992
|
+
e2 = _0_0
|
|
1993
|
+
else: # a > 0, b > 0
|
|
1994
|
+
a, b = (_1_0, b / a) if a > b else (a / b, _1_0)
|
|
1995
|
+
a2b2 = float(a - b) * (a + b)
|
|
1996
|
+
e2 = _over(a2b2, (a**2 if a2 else _0_0) +
|
|
1997
|
+
(b**2 if b2 else _0_0)) if a2b2 else _0_0
|
|
1998
|
+
return e2
|
|
1976
1999
|
|
|
1977
2000
|
|
|
1978
2001
|
def a_b2f(a, b):
|
|
@@ -1986,8 +2009,8 @@ def a_b2f(a, b):
|
|
|
1986
2009
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1987
2010
|
for I{near-spherical} ellipsoids.
|
|
1988
2011
|
'''
|
|
1989
|
-
f = 0 if
|
|
1990
|
-
return _f_0_0 if
|
|
2012
|
+
f = 0 if _ispherical_a_b(a, b) else _over(float(a - b), a)
|
|
2013
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f)
|
|
1991
2014
|
|
|
1992
2015
|
|
|
1993
2016
|
def a_b2f_(a, b):
|
|
@@ -2001,8 +2024,8 @@ def a_b2f_(a, b):
|
|
|
2001
2024
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2002
2025
|
for I{near-spherical} ellipsoids.
|
|
2003
2026
|
'''
|
|
2004
|
-
f_ = 0 if
|
|
2005
|
-
return _f__0_0 if
|
|
2027
|
+
f_ = 0 if _ispherical_a_b(a, b) else _over(a, float(a - b))
|
|
2028
|
+
return _f__0_0 if _ispherical_f_(f_) else Float(f_=f_)
|
|
2006
2029
|
|
|
2007
2030
|
|
|
2008
2031
|
def a_b2f2(a, b):
|
|
@@ -2016,8 +2039,8 @@ def a_b2f2(a, b):
|
|
|
2016
2039
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2017
2040
|
for I{near-spherical} ellipsoids.
|
|
2018
2041
|
'''
|
|
2019
|
-
t = 0 if
|
|
2020
|
-
return Float(f2=_0_0 if fabs(t) < EPS0 else (t
|
|
2042
|
+
t = 0 if _ispherical_a_b(a, b) else float(a - b)
|
|
2043
|
+
return Float(f2=_0_0 if fabs(t) < EPS0 else _over(t, b))
|
|
2021
2044
|
|
|
2022
2045
|
|
|
2023
2046
|
def a_b2n(a, b):
|
|
@@ -2028,11 +2051,11 @@ def a_b2n(a, b):
|
|
|
2028
2051
|
|
|
2029
2052
|
@return: The I{signed}, 3rd flattening (C{scalar} or C{0}), M{(a - b) / (a + b)}.
|
|
2030
2053
|
|
|
2031
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2032
|
-
|
|
2054
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2055
|
+
for I{near-spherical} ellipsoids.
|
|
2033
2056
|
'''
|
|
2034
|
-
t = 0 if
|
|
2035
|
-
return Float(n=_0_0 if fabs(t) < EPS0 else (t
|
|
2057
|
+
t = 0 if _ispherical_a_b(a, b) else float(a - b)
|
|
2058
|
+
return Float(n=_0_0 if fabs(t) < EPS0 else _over(t, a + b))
|
|
2036
2059
|
|
|
2037
2060
|
|
|
2038
2061
|
def a_f2b(a, f):
|
|
@@ -2043,8 +2066,8 @@ def a_f2b(a, f):
|
|
|
2043
2066
|
|
|
2044
2067
|
@return: The polar radius (C{float}), M{a * (1 - f)}.
|
|
2045
2068
|
'''
|
|
2046
|
-
b = a if
|
|
2047
|
-
return Radius_(b=a if
|
|
2069
|
+
b = a if _ispherical_f(f) else (a * (_1_0 - f))
|
|
2070
|
+
return Radius_(b=a if _ispherical_a_b(a, b) else b)
|
|
2048
2071
|
|
|
2049
2072
|
|
|
2050
2073
|
def a_f_2b(a, f_):
|
|
@@ -2055,8 +2078,8 @@ def a_f_2b(a, f_):
|
|
|
2055
2078
|
|
|
2056
2079
|
@return: The polar radius (C{float}), M{a * (f_ - 1) / f_}.
|
|
2057
2080
|
'''
|
|
2058
|
-
b = a if
|
|
2059
|
-
return Radius_(b=a if
|
|
2081
|
+
b = a if _ispherical_f_(f_) else _over(a * (f_ - _1_0), f_)
|
|
2082
|
+
return Radius_(b=a if _ispherical_a_b(a, b) else b)
|
|
2060
2083
|
|
|
2061
2084
|
|
|
2062
2085
|
def b_f2a(b, f):
|
|
@@ -2068,8 +2091,8 @@ def b_f2a(b, f):
|
|
|
2068
2091
|
@return: The equatorial radius (C{float}), M{b / (1 - f)}.
|
|
2069
2092
|
'''
|
|
2070
2093
|
t = _1_0 - f
|
|
2071
|
-
a =
|
|
2072
|
-
return Radius_(a=b if
|
|
2094
|
+
a = b if fabs(t) < EPS0 else _over(b, t)
|
|
2095
|
+
return Radius_(a=b if _ispherical_a_b(a, b) else a)
|
|
2073
2096
|
|
|
2074
2097
|
|
|
2075
2098
|
def b_f_2a(b, f_):
|
|
@@ -2081,9 +2104,9 @@ def b_f_2a(b, f_):
|
|
|
2081
2104
|
@return: The equatorial radius (C{float}), M{b * f_ / (f_ - 1)}.
|
|
2082
2105
|
'''
|
|
2083
2106
|
t = f_ - _1_0
|
|
2084
|
-
a = b if
|
|
2085
|
-
|
|
2086
|
-
return Radius_(a=b if
|
|
2107
|
+
a = b if _ispherical_f_(f_) or fabs(t) < EPS0 \
|
|
2108
|
+
or fabs(t - f_) < EPS0 else _over(b * f_, t)
|
|
2109
|
+
return Radius_(a=b if _ispherical_a_b(a, b) else a)
|
|
2087
2110
|
|
|
2088
2111
|
|
|
2089
2112
|
def e2f(e):
|
|
@@ -2103,9 +2126,9 @@ def e22f(e2):
|
|
|
2103
2126
|
|
|
2104
2127
|
@arg e2: The (1st) eccentricity I{squared}, I{signed} (L{NINF} < C{float} < 1)
|
|
2105
2128
|
|
|
2106
|
-
@return: The flattening (C{float} or C{0}), M{e2 / (sqrt(
|
|
2129
|
+
@return: The flattening (C{float} or C{0}), M{e2 / (sqrt(1 - e2) + 1)}.
|
|
2107
2130
|
'''
|
|
2108
|
-
return Float(f=e2
|
|
2131
|
+
return Float(f=_over(e2, sqrt(_1_0 - e2) + _1_0)) if e2 and e2 < _1_0 else _f_0_0
|
|
2109
2132
|
|
|
2110
2133
|
|
|
2111
2134
|
def f2e2(f):
|
|
@@ -2113,17 +2136,16 @@ def f2e2(f):
|
|
|
2113
2136
|
|
|
2114
2137
|
@arg f: Flattening (C{scalar} < 1, negative for I{prolate}).
|
|
2115
2138
|
|
|
2116
|
-
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} < 1),
|
|
2117
|
-
M{f * (2 - f)}.
|
|
2139
|
+
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} < 1), M{f * (2 - f)}.
|
|
2118
2140
|
|
|
2119
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2120
|
-
|
|
2141
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2142
|
+
for I{near-spherical} ellipsoids.
|
|
2121
2143
|
|
|
2122
2144
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2123
2145
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2124
2146
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2125
2147
|
'''
|
|
2126
|
-
return Float(e2=_0_0 if
|
|
2148
|
+
return Float(e2=_0_0 if _ispherical_f(f) else (f * (_2_0 - f)))
|
|
2127
2149
|
|
|
2128
2150
|
|
|
2129
2151
|
def f2e22(f):
|
|
@@ -2131,18 +2153,18 @@ def f2e22(f):
|
|
|
2131
2153
|
|
|
2132
2154
|
@arg f: Flattening (C{scalar} < 1, negative for I{prolate}).
|
|
2133
2155
|
|
|
2134
|
-
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} > -1 or
|
|
2135
|
-
|
|
2156
|
+
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} > -1 or C{INF}),
|
|
2157
|
+
M{f * (2 - f) / (1 - f)**2}.
|
|
2136
2158
|
|
|
2137
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2138
|
-
|
|
2159
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2160
|
+
for near-spherical ellipsoids.
|
|
2139
2161
|
|
|
2140
2162
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2141
2163
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>}.
|
|
2142
2164
|
'''
|
|
2143
2165
|
# e2 / (1 - e2) == f * (2 - f) / (1 - f)**2
|
|
2144
2166
|
t = (_1_0 - f)**2
|
|
2145
|
-
return Float(e22=INF if t < EPS0 else (f2e2(f)
|
|
2167
|
+
return Float(e22=INF if t < EPS0 else _over(f2e2(f), t)) # PYCHOK type
|
|
2146
2168
|
|
|
2147
2169
|
|
|
2148
2170
|
def f2e32(f):
|
|
@@ -2153,15 +2175,15 @@ def f2e32(f):
|
|
|
2153
2175
|
@return: The I{signed}, 3rd eccentricity I{squared} (C{float}),
|
|
2154
2176
|
M{f * (2 - f) / (1 + (1 - f)**2)}.
|
|
2155
2177
|
|
|
2156
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2157
|
-
|
|
2178
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2179
|
+
for I{near-spherical} ellipsoids.
|
|
2158
2180
|
|
|
2159
2181
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2160
2182
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>}.
|
|
2161
2183
|
'''
|
|
2162
2184
|
# e2 / (2 - e2) == f * (2 - f) / (1 + (1 - f)**2)
|
|
2163
2185
|
e2 = f2e2(f)
|
|
2164
|
-
return Float(e32=e2
|
|
2186
|
+
return Float(e32=_over(e2, _2_0 - e2))
|
|
2165
2187
|
|
|
2166
2188
|
|
|
2167
2189
|
def f_2f(f_):
|
|
@@ -2171,11 +2193,11 @@ def f_2f(f_):
|
|
|
2171
2193
|
|
|
2172
2194
|
@return: The flattening (C{scalar} or C{0}), M{1 / f_}.
|
|
2173
2195
|
|
|
2174
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2175
|
-
|
|
2196
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2197
|
+
for I{near-spherical} ellipsoids.
|
|
2176
2198
|
'''
|
|
2177
|
-
f = 0 if
|
|
2178
|
-
return _f_0_0 if
|
|
2199
|
+
f = 0 if _ispherical_f_(f_) else _over(_1_0, f_)
|
|
2200
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f) # PYCHOK type
|
|
2179
2201
|
|
|
2180
2202
|
|
|
2181
2203
|
def f2f_(f):
|
|
@@ -2185,11 +2207,11 @@ def f2f_(f):
|
|
|
2185
2207
|
|
|
2186
2208
|
@return: The inverse flattening (C{scalar} or C{0}), M{1 / f}.
|
|
2187
2209
|
|
|
2188
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2189
|
-
|
|
2210
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2211
|
+
for I{near-spherical} ellipsoids.
|
|
2190
2212
|
'''
|
|
2191
|
-
f_ = 0 if
|
|
2192
|
-
return _f__0_0 if
|
|
2213
|
+
f_ = 0 if _ispherical_f(f) else _over(_1_0, f)
|
|
2214
|
+
return _f__0_0 if _ispherical_f_(f_) else Float(f_=f_) # PYCHOK type
|
|
2193
2215
|
|
|
2194
2216
|
|
|
2195
2217
|
def f2f2(f):
|
|
@@ -2199,16 +2221,16 @@ def f2f2(f):
|
|
|
2199
2221
|
|
|
2200
2222
|
@return: The I{signed}, 2nd flattening (C{scalar} or C{INF}), M{f / (1 - f)}.
|
|
2201
2223
|
|
|
2202
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2203
|
-
|
|
2224
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2225
|
+
for I{near-spherical} ellipsoids.
|
|
2204
2226
|
|
|
2205
2227
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2206
2228
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2207
2229
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2208
2230
|
'''
|
|
2209
2231
|
t = _1_0 - f
|
|
2210
|
-
return Float(f2=_0_0 if
|
|
2211
|
-
|
|
2232
|
+
return Float(f2=_0_0 if _ispherical_f(f) else
|
|
2233
|
+
(INF if fabs(t) < EPS else _over(f, t))) # PYCHOK type
|
|
2212
2234
|
|
|
2213
2235
|
|
|
2214
2236
|
def f2n(f):
|
|
@@ -2219,14 +2241,14 @@ def f2n(f):
|
|
|
2219
2241
|
@return: The I{signed}, 3rd flattening (-1 <= C{float} < 1),
|
|
2220
2242
|
M{f / (2 - f)}.
|
|
2221
2243
|
|
|
2222
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2223
|
-
|
|
2244
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2245
|
+
for I{near-spherical} ellipsoids.
|
|
2224
2246
|
|
|
2225
2247
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2226
2248
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2227
2249
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2228
2250
|
'''
|
|
2229
|
-
return Float(n=_0_0 if
|
|
2251
|
+
return Float(n=_0_0 if _ispherical_f(f) else _over(f, float(_2_0 - f)))
|
|
2230
2252
|
|
|
2231
2253
|
|
|
2232
2254
|
def n2e2(n):
|
|
@@ -2237,14 +2259,14 @@ def n2e2(n):
|
|
|
2237
2259
|
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or NINF),
|
|
2238
2260
|
M{4 * n / (1 + n)**2}.
|
|
2239
2261
|
|
|
2240
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2241
|
-
|
|
2262
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2263
|
+
for I{near-spherical} ellipsoids.
|
|
2242
2264
|
|
|
2243
2265
|
@see: U{Flattening<https://WikiPedia.org/wiki/Flattening>}.
|
|
2244
2266
|
'''
|
|
2245
2267
|
t = (n + _1_0)**2
|
|
2246
2268
|
return Float(e2=_0_0 if fabs(n) < EPS0 else
|
|
2247
|
-
(NINF if t < EPS0 else (_4_0 * n
|
|
2269
|
+
(NINF if t < EPS0 else _over(_4_0 * n, t)))
|
|
2248
2270
|
|
|
2249
2271
|
|
|
2250
2272
|
def n2f(n):
|
|
@@ -2259,8 +2281,8 @@ def n2f(n):
|
|
|
2259
2281
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2260
2282
|
'''
|
|
2261
2283
|
t = n + _1_0
|
|
2262
|
-
f = 0 if fabs(n) < EPS0 else (NINF if t < EPS0 else (_2_0 * n
|
|
2263
|
-
return _f_0_0 if
|
|
2284
|
+
f = 0 if fabs(n) < EPS0 else (NINF if t < EPS0 else _over(_2_0 * n, t))
|
|
2285
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f)
|
|
2264
2286
|
|
|
2265
2287
|
|
|
2266
2288
|
def n2f_(n):
|
|
@@ -2369,7 +2391,7 @@ Ellipsoids._assert( # <https://WikiPedia.org/wiki/Earth_ellipsoid>
|
|
|
2369
2391
|
|
|
2370
2392
|
_EWGS84 = Ellipsoids.WGS84 # (INTERNAL) shared
|
|
2371
2393
|
|
|
2372
|
-
if __name__ ==
|
|
2394
|
+
if __name__ == _DMAIN_:
|
|
2373
2395
|
|
|
2374
2396
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
2375
2397
|
from pygeodesy import nameof, printf
|
|
@@ -2392,7 +2414,7 @@ if __name__ == '__main__':
|
|
|
2392
2414
|
t = [NN] + Ellipsoids.toRepr(all=True, asorted=True).split(_NL_)
|
|
2393
2415
|
printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
|
|
2394
2416
|
|
|
2395
|
-
# % python3 -m pygeodesy.ellipsoids
|
|
2417
|
+
# % python3.13 -m pygeodesy.ellipsoids
|
|
2396
2418
|
|
|
2397
2419
|
# Ellipsoids.WGS84: name='WGS84', a=6378137, f=0.0033528107, f_=298.257223563, b=6356752.3142451793, f2=0.0033640898, n=0.0016792204, e=0.0818191908, e2=0.00669438, e21=0.99330562, e22=0.0067394967, e32=0.0033584313, A=6367449.1458234144, L=10001965.7293127235, R1=6371008.7714150595, R2=6371007.1809184738, R3=6371000.7900091587, Rbiaxial=6367453.6345163295, Rtriaxial=6372797.5559594007
|
|
2398
2420
|
# e=8.1819190842622e-02, f_=2.98257223563e+02, f=3.3528106647475e-03, n=1.6792203863837e-03 (0.0e+00)
|
|
@@ -2418,7 +2440,7 @@ if __name__ == '__main__':
|
|
|
2418
2440
|
# BetaKs 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
|
2419
2441
|
# KsOrder 8
|
|
2420
2442
|
|
|
2421
|
-
# Ellipsoids._Prolate: name='_Prolate', a=6356752.3142451793, f=-0.0033640898, f_=-297.257223563, b=6378137, f2=-0.0033528107, n=-0.0016792204, e=0.0820944379, e2=-0.0067394967, e21=1.0067394967, e22=-0.00669438, e32=-0.0033584313, A=6367449.1458234144, L=10035500.
|
|
2443
|
+
# Ellipsoids._Prolate: name='_Prolate', a=6356752.3142451793, f=-0.0033640898, f_=-297.257223563, b=6378137, f2=-0.0033528107, n=-0.0016792204, e=0.0820944379, e2=-0.0067394967, e21=1.0067394967, e22=-0.00669438, e32=-0.0033584313, A=6367449.1458234144, L=10035500.5204500332, R1=6363880.5428301189, R2=6363878.9413582645, R3=6363872.5644020075, Rbiaxial=6367453.6345163295, Rtriaxial=6362105.2243882557
|
|
2422
2444
|
# e=8.2094437949696e-02, f_=-2.97257223563e+02, f=-3.3640898209765e-03, n=-1.6792203863837e-03 (0.0e+00)
|
|
2423
2445
|
# AlphaKs -0.00084149152514366627, 0.00000076653480614871, -0.00000000120934503389, 0.0000000000024576225, -0.00000000000000578863, 0.00000000000000001502, -0.00000000000000000004, 0.0
|
|
2424
2446
|
# BetaKs -0.00084149187224351817, 0.00000005842735196773, -0.0000000001680487236, 0.00000000000021706261, -0.00000000000000038002, 0.00000000000000000073, -0.0, 0.0
|