pygeodesy 25.4.8__py2.py3-none-any.whl → 25.4.25__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 +30 -27
- 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 +31 -17
- pygeodesy/booleans.py +12 -10
- pygeodesy/cartesianBase.py +21 -20
- 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 +10 -7
- 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 +167 -138
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +7 -7
- pygeodesy/fmath.py +10 -9
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +78 -77
- 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 +14 -18
- pygeodesy/lazily.py +65 -63
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +8 -7
- pygeodesy/ltpTuples.py +2 -2
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +47 -31
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +11 -10
- 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 +88 -18
- pygeodesy/vector2d.py +18 -11
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +27 -23
- pygeodesy-25.4.25.dist-info/RECORD +118 -0
- pygeodesy-25.4.8.dist-info/RECORD +0 -118
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.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.23'
|
|
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):
|
|
@@ -243,7 +245,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
243
245
|
if not _isfinite(a):
|
|
244
246
|
raise ValueError(_SPACE_(_a_, _not_finite_))
|
|
245
247
|
|
|
246
|
-
if b: # not
|
|
248
|
+
if b: # not _isin(b, None, _0_0)
|
|
247
249
|
b = Radius_(b=b) # low=EPS
|
|
248
250
|
f = a_b2f(a, b) if f is None else Float(f=f)
|
|
249
251
|
f_ = f2f_(f) if f_ is None else Float(f_=f_)
|
|
@@ -424,7 +426,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
424
426
|
t = Fmt.EQUAL(self._DOT_(n), t)
|
|
425
427
|
raise Error(t, txt=txt or Fmt.exceeds_eps(eps))
|
|
426
428
|
return Float(v if self.f else f0, name=n)
|
|
427
|
-
raise Error(unstr(self._DOT_(self._assert
|
|
429
|
+
raise Error(unstr(self._DOT_(typename(self._assert)), val,
|
|
428
430
|
eps=eps, f0=f0, **name_value))
|
|
429
431
|
|
|
430
432
|
def auxAuthalic(self, lat, inverse=False):
|
|
@@ -442,7 +444,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
442
444
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, p 16.
|
|
443
445
|
'''
|
|
444
446
|
if self.f:
|
|
445
|
-
f
|
|
447
|
+
f = self._albersCyl._tanf if inverse else \
|
|
448
|
+
self._albersCyl._txif # PYCHOK attr
|
|
446
449
|
lat = atan1d(f(tan(Phid(lat)))) # PYCHOK attr
|
|
447
450
|
return _aux(lat, inverse, Ellipsoid.auxAuthalic)
|
|
448
451
|
|
|
@@ -461,7 +464,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
461
464
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 15-16.
|
|
462
465
|
'''
|
|
463
466
|
if self.f:
|
|
464
|
-
f
|
|
467
|
+
f = self.es_tauf if inverse else self.es_taupf # PYCHOK attr
|
|
465
468
|
lat = atan1d(f(tan(Phid(lat)))) # PYCHOK attr
|
|
466
469
|
return _aux(lat, inverse, Ellipsoid.auxConformal)
|
|
467
470
|
|
|
@@ -480,8 +483,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
480
483
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 17-18.
|
|
481
484
|
'''
|
|
482
485
|
if self.f:
|
|
483
|
-
f
|
|
484
|
-
lat = atan1d(
|
|
486
|
+
f = self.a2_b2 if inverse else self.b2_a2
|
|
487
|
+
lat = atan1d(tan(Phid(lat)) * f)
|
|
485
488
|
return _aux(lat, inverse, Ellipsoid.auxGeocentric)
|
|
486
489
|
|
|
487
490
|
def auxIsometric(self, lat, inverse=False):
|
|
@@ -503,7 +506,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
503
506
|
U{Snyder<https://Pubs.USGS.gov/pp/1395/report.pdf>}, pp 15-16.
|
|
504
507
|
'''
|
|
505
508
|
if self.f:
|
|
506
|
-
r
|
|
509
|
+
r = Phid(lat, clip=0)
|
|
507
510
|
lat = degrees(atan1(self.es_tauf(sinh(r))) if inverse else
|
|
508
511
|
asinh(self.es_taupf(tan(r))))
|
|
509
512
|
# clip=0, since auxIsometric(+/-90) is far outside [-90..+90]
|
|
@@ -549,9 +552,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
549
552
|
if inverse:
|
|
550
553
|
e = self._elliptic_e22
|
|
551
554
|
d = degrees90(e.fEinv(e.cE * lat / _90_0))
|
|
552
|
-
lat =
|
|
555
|
+
lat = self.auxParametric(d, inverse=True)
|
|
553
556
|
else:
|
|
554
|
-
lat =
|
|
557
|
+
lat = _over(self.Llat(lat), self.L) * _90_0
|
|
555
558
|
return _aux(lat, inverse, Ellipsoid.auxRectifying)
|
|
556
559
|
|
|
557
560
|
@Property_RO
|
|
@@ -582,7 +585,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
582
585
|
|
|
583
586
|
@see: U{Radii of Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
584
587
|
'''
|
|
585
|
-
return Radius(b2_a=self.b2
|
|
588
|
+
return Radius(b2_a=_over(self.b2, self.a) if self.f else self.b)
|
|
586
589
|
|
|
587
590
|
@Property_RO
|
|
588
591
|
def b2_a2(self):
|
|
@@ -831,7 +834,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
831
834
|
def _elliptic_e12(self): # see I{Karney}'s Ellipsoid._e12
|
|
832
835
|
'''(INTERNAL) Elliptic helper for C{Rhumb}.
|
|
833
836
|
'''
|
|
834
|
-
e12 = self.e2
|
|
837
|
+
e12 = _over(self.e2, self.e2 - _1_0) # NOT DEPRECATED .e12!
|
|
835
838
|
return _MODS.elliptic.Elliptic(e12)
|
|
836
839
|
|
|
837
840
|
@Property_RO
|
|
@@ -869,7 +872,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
869
872
|
if r < 0:
|
|
870
873
|
raise ValueError(_negative_)
|
|
871
874
|
except (TypeError, ValueError) as x:
|
|
872
|
-
t = self._DOT_(Ellipsoid.e2s2
|
|
875
|
+
t = self._DOT_(typename(Ellipsoid.e2s2))
|
|
873
876
|
raise _ValueError(t, s, cause=x)
|
|
874
877
|
return r
|
|
875
878
|
|
|
@@ -919,8 +922,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
919
922
|
'''
|
|
920
923
|
t = Scalar(taup=taup)
|
|
921
924
|
if self.f: # .isEllipsoidal
|
|
922
|
-
a =
|
|
923
|
-
T =
|
|
925
|
+
a = fabs(t)
|
|
926
|
+
T = (self._exp_es_atanh_1 if a > 70 else self._1_e21) * t
|
|
924
927
|
if fabs(T * _EPSqrt) < _2_0: # handles +/- INF and NAN
|
|
925
928
|
s = (a * _TOL) if a > _1_0 else _TOL
|
|
926
929
|
for T, _, d in self._es_tauf3(t, T): # max 2
|
|
@@ -939,8 +942,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
939
942
|
_tf2 = self._es_taupf2
|
|
940
943
|
for i in range(1, N + 1):
|
|
941
944
|
a, h = _tf2(T)
|
|
942
|
-
d = (taup - a) * (e + T**2) / (hypot1(a) * h)
|
|
943
945
|
# = (taup - a) / hypot1(a) / ((e + T**2) / h)
|
|
946
|
+
d = _over((taup - a) * (T**2 + e), hypot1(a) * h)
|
|
944
947
|
T, d = _F2_(d) # τi, (τi - τi-1)
|
|
945
948
|
yield T, i, d
|
|
946
949
|
|
|
@@ -1085,8 +1088,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1085
1088
|
|
|
1086
1089
|
@arg pov: Point-Of-View outside this ellipsoid (C{Cartesian}, L{Ecef9Tuple}
|
|
1087
1090
|
or L{Vector3d}).
|
|
1088
|
-
@kwarg los: Line-Of-Sight, I{direction} to this ellipsoid (L{Vector3d})
|
|
1089
|
-
C{
|
|
1091
|
+
@kwarg los: Line-Of-Sight, I{direction} to this ellipsoid (L{Los}, L{Vector3d})
|
|
1092
|
+
or C{True} for the I{normal, perpendicular, plumb} to the surface
|
|
1093
|
+
of this ellipsoid or C{False} or C{None} to point to its center.
|
|
1090
1094
|
|
|
1091
1095
|
@return: L{Vector4Tuple}C{(x, y, z, h)} with the cartesian coordinates C{x},
|
|
1092
1096
|
C{y} and C{z} of the projection on or the intersection with this
|
|
@@ -1095,8 +1099,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1095
1099
|
|
|
1096
1100
|
@raise IntersectionError: Null B{C{pov}} or B{C{los}} vector, or B{C{pov}}
|
|
1097
1101
|
is inside this ellipsoid or B{C{los}} points
|
|
1098
|
-
outside this ellipsoid or
|
|
1099
|
-
direction.
|
|
1102
|
+
outside this ellipsoid or in opposite direction.
|
|
1100
1103
|
|
|
1101
1104
|
@raise TypeError: Invalid B{C{pov}} or B{C{los}}.
|
|
1102
1105
|
|
|
@@ -1105,10 +1108,10 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1105
1108
|
methods L{Ellipsoid.height4} and L{Triaxial.hartzell4}.
|
|
1106
1109
|
'''
|
|
1107
1110
|
try:
|
|
1108
|
-
v, d,
|
|
1111
|
+
v, d, i = _MODS.triaxials._hartzell3(pov, los, self._triaxial)
|
|
1109
1112
|
except Exception as x:
|
|
1110
1113
|
raise IntersectionError(pov=pov, los=los, cause=x)
|
|
1111
|
-
return Vector4Tuple(v.x, v.y, v.z, d, name__=self.hartzell4)
|
|
1114
|
+
return Vector4Tuple(v.x, v.y, v.z, d, iteration=i, name__=self.hartzell4)
|
|
1112
1115
|
|
|
1113
1116
|
@Property_RO
|
|
1114
1117
|
def _hash(self):
|
|
@@ -1164,10 +1167,10 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1164
1167
|
h = t.minus(v).length
|
|
1165
1168
|
|
|
1166
1169
|
else: # radial to ellipsoid's center
|
|
1167
|
-
h =
|
|
1170
|
+
h = hypot_(a * v.z, b * v.x, b * v.y)
|
|
1168
1171
|
t = (a * b / h) if h > EPS0 else _0_0 # EPS
|
|
1169
|
-
v =
|
|
1170
|
-
h =
|
|
1172
|
+
v = v.times(t)
|
|
1173
|
+
h = r * (_1_0 - t)
|
|
1171
1174
|
|
|
1172
1175
|
return Vector4Tuple(v.x, v.y, v.z, h, iteration=i, name__=self.height4)
|
|
1173
1176
|
|
|
@@ -1238,7 +1241,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1238
1241
|
|
|
1239
1242
|
@raise ValueError: Invalid B{C{order}}.
|
|
1240
1243
|
'''
|
|
1241
|
-
if not (isint(order) and order
|
|
1244
|
+
if not (isint(order) and _isin(order, 4, 6, 8)):
|
|
1242
1245
|
raise _ValueError(order=order)
|
|
1243
1246
|
if self._KsOrder != order:
|
|
1244
1247
|
Ellipsoid.AlphaKs._update(self)
|
|
@@ -1302,8 +1305,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1302
1305
|
return degrees(self.m2radians(distance, lat=lat))
|
|
1303
1306
|
|
|
1304
1307
|
def m2radians(self, distance, lat=0):
|
|
1305
|
-
'''Convert a distance to an angle along the equator or
|
|
1306
|
-
|
|
1308
|
+
'''Convert a distance to an angle along the equator or along
|
|
1309
|
+
a parallel of (geodetic) latitude.
|
|
1307
1310
|
|
|
1308
1311
|
@arg distance: Distance (C{meter}).
|
|
1309
1312
|
@kwarg lat: Parallel latitude (C{degrees90}, C{str}).
|
|
@@ -1646,19 +1649,26 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1646
1649
|
r = self.e2s2(sin(a))
|
|
1647
1650
|
if r > EPS02:
|
|
1648
1651
|
n = self.a / sqrt(r)
|
|
1649
|
-
m = n *
|
|
1652
|
+
m = n * self.e21 / r
|
|
1650
1653
|
else:
|
|
1651
1654
|
m = n = _0_0
|
|
1652
1655
|
else:
|
|
1653
1656
|
m = n = self.a
|
|
1654
1657
|
if scaled and a:
|
|
1655
1658
|
n *= cos(a) if a < PI_2 else _0_0
|
|
1656
|
-
return Curvature2Tuple(
|
|
1657
|
-
|
|
1659
|
+
return Curvature2Tuple(m, n)
|
|
1660
|
+
|
|
1661
|
+
def rocAzimuth(self, lat, azimuth):
|
|
1662
|
+
'''Compute the I{directional} radius of curvature of (geodetic) latitude
|
|
1663
|
+
and C{azimuth} compass direction.
|
|
1664
|
+
|
|
1665
|
+
@see: Method L{rocBearing<Ellipsoid.rocBearing>} for details, using C{azimuth} for C{bearing}.
|
|
1666
|
+
'''
|
|
1667
|
+
return Radius(rocAzimuth=self._rocDirectional(lat, Azimuth(azimuth)))
|
|
1658
1668
|
|
|
1659
1669
|
def rocBearing(self, lat, bearing):
|
|
1660
|
-
'''Compute the I{directional} radius of curvature of (geodetic)
|
|
1661
|
-
|
|
1670
|
+
'''Compute the I{directional} radius of curvature of (geodetic) latitude
|
|
1671
|
+
and C{bearing} compass direction.
|
|
1662
1672
|
|
|
1663
1673
|
@arg lat: Latitude (C{degrees90}).
|
|
1664
1674
|
@arg bearing: Direction (compass C{degrees360}).
|
|
@@ -1672,18 +1682,23 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1672
1682
|
|
|
1673
1683
|
@see: U{Radii of Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}
|
|
1674
1684
|
'''
|
|
1685
|
+
return Radius(rocBearing=self._rocDirectional(lat, Bearing(bearing)))
|
|
1686
|
+
|
|
1687
|
+
def _rocDirectional(self, lat, deg):
|
|
1688
|
+
'''(INTERNAL) Helper for C{rocAzimuth} and C{rocBearing}.
|
|
1689
|
+
'''
|
|
1675
1690
|
if self.f:
|
|
1676
|
-
s2, c2 = _s2_c2(
|
|
1691
|
+
s2, c2 = _s2_c2(radians(deg))
|
|
1677
1692
|
m, n = self.roc2_(Phid(lat))
|
|
1678
1693
|
if n < m: # == n / (c2 * n / m + s2)
|
|
1679
1694
|
c2 *= n / m
|
|
1680
1695
|
elif m < n: # == m / (c2 + s2 * m / n)
|
|
1681
1696
|
s2 *= m / n
|
|
1682
|
-
n
|
|
1683
|
-
|
|
1697
|
+
n = m
|
|
1698
|
+
r = _over(n, c2 + s2) # == 1 / (c2 / m + s2 / n)
|
|
1684
1699
|
else:
|
|
1685
|
-
|
|
1686
|
-
return
|
|
1700
|
+
r = self.b # == self.a
|
|
1701
|
+
return r
|
|
1687
1702
|
|
|
1688
1703
|
@Property_RO
|
|
1689
1704
|
def rocEquatorial2(self):
|
|
@@ -1694,8 +1709,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1694
1709
|
L{a2_b}, C{rocPolar} and polar and equatorial U{Radii of Curvature
|
|
1695
1710
|
<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
1696
1711
|
'''
|
|
1697
|
-
|
|
1698
|
-
|
|
1712
|
+
m = self.b2_a if self.f else self.a
|
|
1713
|
+
return Curvature2Tuple(m, self.a)
|
|
1699
1714
|
|
|
1700
1715
|
def rocGauss(self, lat):
|
|
1701
1716
|
'''Compute the I{Gaussian} radius of curvature of (geodetic) latitude.
|
|
@@ -1716,7 +1731,7 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1716
1731
|
g = self.b
|
|
1717
1732
|
if self.f:
|
|
1718
1733
|
s2, c2 = _s2_c2(Phid(lat))
|
|
1719
|
-
g = g
|
|
1734
|
+
g = _over(g, c2 + self.b2_a2 * s2)
|
|
1720
1735
|
return Radius(rocGauss=g)
|
|
1721
1736
|
|
|
1722
1737
|
def rocMean(self, lat):
|
|
@@ -1733,9 +1748,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1733
1748
|
'''
|
|
1734
1749
|
if self.f:
|
|
1735
1750
|
m, n = self.roc2_(Phid(lat))
|
|
1736
|
-
m *= n * _2_0
|
|
1751
|
+
m *= _over(n * _2_0, m + n) # == 2 / (1 / m + 1 / n)
|
|
1737
1752
|
else:
|
|
1738
|
-
m =
|
|
1753
|
+
m = self.a
|
|
1739
1754
|
return Radius(rocMean=m)
|
|
1740
1755
|
|
|
1741
1756
|
def rocMeridional(self, lat):
|
|
@@ -1751,8 +1766,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1751
1766
|
<https://www.EdWilliams.org/avform.htm#flat>} and U{Radii of
|
|
1752
1767
|
Curvature<https://WikiPedia.org/wiki/Earth_radius#Radii_of_curvature>}.
|
|
1753
1768
|
'''
|
|
1754
|
-
|
|
1755
|
-
|
|
1769
|
+
r = self.roc2_(Phid(lat)) if lat else self.rocEquatorial2
|
|
1770
|
+
return Radius(rocMeridional=r.meridional)
|
|
1756
1771
|
|
|
1757
1772
|
rocPolar = a2_b # synonymous
|
|
1758
1773
|
|
|
@@ -1771,8 +1786,8 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1771
1786
|
U{Radii of Curvature<https://WikiPedia.org/wiki/
|
|
1772
1787
|
Earth_radius#Radii_of_curvature>}.
|
|
1773
1788
|
'''
|
|
1774
|
-
|
|
1775
|
-
|
|
1789
|
+
r = self.roc2_(Phid(lat)) if lat else self.rocEquatorial2
|
|
1790
|
+
return Radius(rocPrimeVertical=r.prime_vertical)
|
|
1776
1791
|
|
|
1777
1792
|
rocTransverse = rocPrimeVertical # synonymous
|
|
1778
1793
|
|
|
@@ -1792,7 +1807,9 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1792
1807
|
|
|
1793
1808
|
@see: U{Earth radius<https://WikiPedia.org/wiki/Earth_radius>}.
|
|
1794
1809
|
'''
|
|
1795
|
-
r =
|
|
1810
|
+
r = self.a
|
|
1811
|
+
if self.f:
|
|
1812
|
+
r *= cbrt2((sqrt3(self.b_a) + _1_0) * _0_5)
|
|
1796
1813
|
return Radius(Rrectifying=r)
|
|
1797
1814
|
|
|
1798
1815
|
@deprecated_Property_RO
|
|
@@ -1806,9 +1823,11 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1806
1823
|
|
|
1807
1824
|
@see: C{Rbiaxial}
|
|
1808
1825
|
'''
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1826
|
+
q, b = self.a, self.b
|
|
1827
|
+
if b < q:
|
|
1828
|
+
q *= sqrt((self.b2_a2 + _3_0) * _0_25)
|
|
1829
|
+
elif b > q:
|
|
1830
|
+
q = sqrt((self.a2_b2 * _3_0 + _1_0) * _0_25) * b
|
|
1812
1831
|
return Radius(Rtriaxial=q)
|
|
1813
1832
|
|
|
1814
1833
|
def toEllipsoid2(self, **name):
|
|
@@ -1897,22 +1916,23 @@ class Ellipsoid2(Ellipsoid):
|
|
|
1897
1916
|
Ellipsoid.__init__(self, a, f=f, **name)
|
|
1898
1917
|
|
|
1899
1918
|
|
|
1900
|
-
def
|
|
1919
|
+
def _ispherical_a_b(a, b):
|
|
1901
1920
|
'''(INTERNAL) C{True} for spherical or invalid C{a} or C{b}.
|
|
1902
1921
|
'''
|
|
1903
1922
|
return a < EPS0 or b < EPS0 or fabs(a - b) < EPS0
|
|
1904
1923
|
|
|
1905
1924
|
|
|
1906
|
-
def
|
|
1925
|
+
def _ispherical_f(f):
|
|
1907
1926
|
'''(INTERNAL) C{True} for spherical or invalid C{f}.
|
|
1908
1927
|
'''
|
|
1909
|
-
return
|
|
1928
|
+
return f > EPS1 or fabs(f) < EPS
|
|
1910
1929
|
|
|
1911
1930
|
|
|
1912
|
-
def
|
|
1931
|
+
def _ispherical_f_(f_):
|
|
1913
1932
|
'''(INTERNAL) C{True} for spherical or invalid C{f_}.
|
|
1914
1933
|
'''
|
|
1915
|
-
|
|
1934
|
+
f_ = fabs(f_)
|
|
1935
|
+
return f_ < EPS or f_ > _1_EPS
|
|
1916
1936
|
|
|
1917
1937
|
|
|
1918
1938
|
def a_b2e(a, b):
|
|
@@ -1921,12 +1941,12 @@ def a_b2e(a, b):
|
|
|
1921
1941
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1922
1942
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1923
1943
|
|
|
1924
|
-
@return: The I{unsigned}, (1st) eccentricity (C{float} or C{0}),
|
|
1925
|
-
M{sqrt(1 - (b / a)**2)}.
|
|
1944
|
+
@return: The I{unsigned}, (1st) eccentricity (C{float} or C{0}), M{sqrt(1 - (b / a)**2)}.
|
|
1926
1945
|
|
|
1927
1946
|
@note: The result is always I{non-negative} and C{0} for I{near-spherical} ellipsoids.
|
|
1928
1947
|
'''
|
|
1929
|
-
|
|
1948
|
+
e2 = _a2b2e2(a, b, b2=False)
|
|
1949
|
+
return Float(e=sqrt(fabs(e2)) if e2 else _0_0) # == sqrt(fabs((a - b) * (a + b))) / a
|
|
1930
1950
|
|
|
1931
1951
|
|
|
1932
1952
|
def a_b2e2(a, b):
|
|
@@ -1935,13 +1955,12 @@ def a_b2e2(a, b):
|
|
|
1935
1955
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1936
1956
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1937
1957
|
|
|
1938
|
-
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or C{0}),
|
|
1939
|
-
M{1 - (b / a)**2}.
|
|
1958
|
+
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or C{0}), M{1 - (b / a)**2}.
|
|
1940
1959
|
|
|
1941
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1942
|
-
|
|
1960
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1961
|
+
for I{near-spherical} ellipsoids.
|
|
1943
1962
|
'''
|
|
1944
|
-
return Float(e2=
|
|
1963
|
+
return Float(e2=_a2b2e2(a, b, b2=False))
|
|
1945
1964
|
|
|
1946
1965
|
|
|
1947
1966
|
def a_b2e22(a, b):
|
|
@@ -1950,13 +1969,12 @@ def a_b2e22(a, b):
|
|
|
1950
1969
|
@arg a: Equatorial radius (C{scalar} > 0).
|
|
1951
1970
|
@arg b: Polar radius (C{scalar} > 0).
|
|
1952
1971
|
|
|
1953
|
-
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} or C{0}),
|
|
1954
|
-
M{(a / b)**2 - 1}.
|
|
1972
|
+
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} or C{0}), M{(a / b)**2 - 1}.
|
|
1955
1973
|
|
|
1956
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1957
|
-
|
|
1974
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1975
|
+
for I{near-spherical} ellipsoids.
|
|
1958
1976
|
'''
|
|
1959
|
-
return Float(e22=
|
|
1977
|
+
return Float(e22=_a2b2e2(a, b, a2=False))
|
|
1960
1978
|
|
|
1961
1979
|
|
|
1962
1980
|
def a_b2e32(a, b):
|
|
@@ -1968,11 +1986,23 @@ def a_b2e32(a, b):
|
|
|
1968
1986
|
@return: The I{signed}, 3rd eccentricity I{squared} (C{float} or C{0}),
|
|
1969
1987
|
M{(a**2 - b**2) / (a**2 + b**2)}.
|
|
1970
1988
|
|
|
1971
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
1972
|
-
|
|
1989
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1990
|
+
for I{near-spherical} ellipsoids.
|
|
1991
|
+
'''
|
|
1992
|
+
return Float(e32=_a2b2e2(a, b))
|
|
1993
|
+
|
|
1994
|
+
|
|
1995
|
+
def _a2b2e2(a, b, a2=True, b2=True):
|
|
1996
|
+
'''(INTERNAL) Helper for C{a_b2e}, C{a_b2e2}, C{a_b2e22} and C{a_b2e32}.
|
|
1973
1997
|
'''
|
|
1974
|
-
|
|
1975
|
-
|
|
1998
|
+
if _ispherical_a_b(a, b):
|
|
1999
|
+
e2 = _0_0
|
|
2000
|
+
else: # a > 0, b > 0
|
|
2001
|
+
a, b = (_1_0, b / a) if a > b else (a / b, _1_0)
|
|
2002
|
+
a2b2 = float(a - b) * (a + b)
|
|
2003
|
+
e2 = _over(a2b2, (a**2 if a2 else _0_0) +
|
|
2004
|
+
(b**2 if b2 else _0_0)) if a2b2 else _0_0
|
|
2005
|
+
return e2
|
|
1976
2006
|
|
|
1977
2007
|
|
|
1978
2008
|
def a_b2f(a, b):
|
|
@@ -1986,8 +2016,8 @@ def a_b2f(a, b):
|
|
|
1986
2016
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
1987
2017
|
for I{near-spherical} ellipsoids.
|
|
1988
2018
|
'''
|
|
1989
|
-
f = 0 if
|
|
1990
|
-
return _f_0_0 if
|
|
2019
|
+
f = 0 if _ispherical_a_b(a, b) else _over(float(a - b), a)
|
|
2020
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f)
|
|
1991
2021
|
|
|
1992
2022
|
|
|
1993
2023
|
def a_b2f_(a, b):
|
|
@@ -2001,8 +2031,8 @@ def a_b2f_(a, b):
|
|
|
2001
2031
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2002
2032
|
for I{near-spherical} ellipsoids.
|
|
2003
2033
|
'''
|
|
2004
|
-
f_ = 0 if
|
|
2005
|
-
return _f__0_0 if
|
|
2034
|
+
f_ = 0 if _ispherical_a_b(a, b) else _over(a, float(a - b))
|
|
2035
|
+
return _f__0_0 if _ispherical_f_(f_) else Float(f_=f_)
|
|
2006
2036
|
|
|
2007
2037
|
|
|
2008
2038
|
def a_b2f2(a, b):
|
|
@@ -2016,8 +2046,8 @@ def a_b2f2(a, b):
|
|
|
2016
2046
|
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2017
2047
|
for I{near-spherical} ellipsoids.
|
|
2018
2048
|
'''
|
|
2019
|
-
t = 0 if
|
|
2020
|
-
return Float(f2=_0_0 if fabs(t) < EPS0 else (t
|
|
2049
|
+
t = 0 if _ispherical_a_b(a, b) else float(a - b)
|
|
2050
|
+
return Float(f2=_0_0 if fabs(t) < EPS0 else _over(t, b))
|
|
2021
2051
|
|
|
2022
2052
|
|
|
2023
2053
|
def a_b2n(a, b):
|
|
@@ -2028,11 +2058,11 @@ def a_b2n(a, b):
|
|
|
2028
2058
|
|
|
2029
2059
|
@return: The I{signed}, 3rd flattening (C{scalar} or C{0}), M{(a - b) / (a + b)}.
|
|
2030
2060
|
|
|
2031
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2032
|
-
|
|
2061
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2062
|
+
for I{near-spherical} ellipsoids.
|
|
2033
2063
|
'''
|
|
2034
|
-
t = 0 if
|
|
2035
|
-
return Float(n=_0_0 if fabs(t) < EPS0 else (t
|
|
2064
|
+
t = 0 if _ispherical_a_b(a, b) else float(a - b)
|
|
2065
|
+
return Float(n=_0_0 if fabs(t) < EPS0 else _over(t, a + b))
|
|
2036
2066
|
|
|
2037
2067
|
|
|
2038
2068
|
def a_f2b(a, f):
|
|
@@ -2043,8 +2073,8 @@ def a_f2b(a, f):
|
|
|
2043
2073
|
|
|
2044
2074
|
@return: The polar radius (C{float}), M{a * (1 - f)}.
|
|
2045
2075
|
'''
|
|
2046
|
-
b = a if
|
|
2047
|
-
return Radius_(b=a if
|
|
2076
|
+
b = a if _ispherical_f(f) else (a * (_1_0 - f))
|
|
2077
|
+
return Radius_(b=a if _ispherical_a_b(a, b) else b)
|
|
2048
2078
|
|
|
2049
2079
|
|
|
2050
2080
|
def a_f_2b(a, f_):
|
|
@@ -2055,8 +2085,8 @@ def a_f_2b(a, f_):
|
|
|
2055
2085
|
|
|
2056
2086
|
@return: The polar radius (C{float}), M{a * (f_ - 1) / f_}.
|
|
2057
2087
|
'''
|
|
2058
|
-
b = a if
|
|
2059
|
-
return Radius_(b=a if
|
|
2088
|
+
b = a if _ispherical_f_(f_) else _over(a * (f_ - _1_0), f_)
|
|
2089
|
+
return Radius_(b=a if _ispherical_a_b(a, b) else b)
|
|
2060
2090
|
|
|
2061
2091
|
|
|
2062
2092
|
def b_f2a(b, f):
|
|
@@ -2068,8 +2098,8 @@ def b_f2a(b, f):
|
|
|
2068
2098
|
@return: The equatorial radius (C{float}), M{b / (1 - f)}.
|
|
2069
2099
|
'''
|
|
2070
2100
|
t = _1_0 - f
|
|
2071
|
-
a =
|
|
2072
|
-
return Radius_(a=b if
|
|
2101
|
+
a = b if fabs(t) < EPS0 else _over(b, t)
|
|
2102
|
+
return Radius_(a=b if _ispherical_a_b(a, b) else a)
|
|
2073
2103
|
|
|
2074
2104
|
|
|
2075
2105
|
def b_f_2a(b, f_):
|
|
@@ -2081,9 +2111,9 @@ def b_f_2a(b, f_):
|
|
|
2081
2111
|
@return: The equatorial radius (C{float}), M{b * f_ / (f_ - 1)}.
|
|
2082
2112
|
'''
|
|
2083
2113
|
t = f_ - _1_0
|
|
2084
|
-
a = b if
|
|
2085
|
-
|
|
2086
|
-
return Radius_(a=b if
|
|
2114
|
+
a = b if _ispherical_f_(f_) or fabs(t) < EPS0 \
|
|
2115
|
+
or fabs(t - f_) < EPS0 else _over(b * f_, t)
|
|
2116
|
+
return Radius_(a=b if _ispherical_a_b(a, b) else a)
|
|
2087
2117
|
|
|
2088
2118
|
|
|
2089
2119
|
def e2f(e):
|
|
@@ -2103,9 +2133,9 @@ def e22f(e2):
|
|
|
2103
2133
|
|
|
2104
2134
|
@arg e2: The (1st) eccentricity I{squared}, I{signed} (L{NINF} < C{float} < 1)
|
|
2105
2135
|
|
|
2106
|
-
@return: The flattening (C{float} or C{0}), M{e2 / (sqrt(
|
|
2136
|
+
@return: The flattening (C{float} or C{0}), M{e2 / (sqrt(1 - e2) + 1)}.
|
|
2107
2137
|
'''
|
|
2108
|
-
return Float(f=e2
|
|
2138
|
+
return Float(f=_over(e2, sqrt(_1_0 - e2) + _1_0)) if e2 and e2 < _1_0 else _f_0_0
|
|
2109
2139
|
|
|
2110
2140
|
|
|
2111
2141
|
def f2e2(f):
|
|
@@ -2113,17 +2143,16 @@ def f2e2(f):
|
|
|
2113
2143
|
|
|
2114
2144
|
@arg f: Flattening (C{scalar} < 1, negative for I{prolate}).
|
|
2115
2145
|
|
|
2116
|
-
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} < 1),
|
|
2117
|
-
M{f * (2 - f)}.
|
|
2146
|
+
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} < 1), M{f * (2 - f)}.
|
|
2118
2147
|
|
|
2119
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2120
|
-
|
|
2148
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2149
|
+
for I{near-spherical} ellipsoids.
|
|
2121
2150
|
|
|
2122
2151
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2123
2152
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2124
2153
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2125
2154
|
'''
|
|
2126
|
-
return Float(e2=_0_0 if
|
|
2155
|
+
return Float(e2=_0_0 if _ispherical_f(f) else (f * (_2_0 - f)))
|
|
2127
2156
|
|
|
2128
2157
|
|
|
2129
2158
|
def f2e22(f):
|
|
@@ -2131,18 +2160,18 @@ def f2e22(f):
|
|
|
2131
2160
|
|
|
2132
2161
|
@arg f: Flattening (C{scalar} < 1, negative for I{prolate}).
|
|
2133
2162
|
|
|
2134
|
-
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} > -1 or
|
|
2135
|
-
|
|
2163
|
+
@return: The I{signed}, 2nd eccentricity I{squared} (C{float} > -1 or C{INF}),
|
|
2164
|
+
M{f * (2 - f) / (1 - f)**2}.
|
|
2136
2165
|
|
|
2137
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2138
|
-
|
|
2166
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2167
|
+
for near-spherical ellipsoids.
|
|
2139
2168
|
|
|
2140
2169
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2141
2170
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>}.
|
|
2142
2171
|
'''
|
|
2143
2172
|
# e2 / (1 - e2) == f * (2 - f) / (1 - f)**2
|
|
2144
2173
|
t = (_1_0 - f)**2
|
|
2145
|
-
return Float(e22=INF if t < EPS0 else (f2e2(f)
|
|
2174
|
+
return Float(e22=INF if t < EPS0 else _over(f2e2(f), t)) # PYCHOK type
|
|
2146
2175
|
|
|
2147
2176
|
|
|
2148
2177
|
def f2e32(f):
|
|
@@ -2153,15 +2182,15 @@ def f2e32(f):
|
|
|
2153
2182
|
@return: The I{signed}, 3rd eccentricity I{squared} (C{float}),
|
|
2154
2183
|
M{f * (2 - f) / (1 + (1 - f)**2)}.
|
|
2155
2184
|
|
|
2156
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2157
|
-
|
|
2185
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2186
|
+
for I{near-spherical} ellipsoids.
|
|
2158
2187
|
|
|
2159
2188
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2160
2189
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>}.
|
|
2161
2190
|
'''
|
|
2162
2191
|
# e2 / (2 - e2) == f * (2 - f) / (1 + (1 - f)**2)
|
|
2163
2192
|
e2 = f2e2(f)
|
|
2164
|
-
return Float(e32=e2
|
|
2193
|
+
return Float(e32=_over(e2, _2_0 - e2))
|
|
2165
2194
|
|
|
2166
2195
|
|
|
2167
2196
|
def f_2f(f_):
|
|
@@ -2171,11 +2200,11 @@ def f_2f(f_):
|
|
|
2171
2200
|
|
|
2172
2201
|
@return: The flattening (C{scalar} or C{0}), M{1 / f_}.
|
|
2173
2202
|
|
|
2174
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2175
|
-
|
|
2203
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2204
|
+
for I{near-spherical} ellipsoids.
|
|
2176
2205
|
'''
|
|
2177
|
-
f = 0 if
|
|
2178
|
-
return _f_0_0 if
|
|
2206
|
+
f = 0 if _ispherical_f_(f_) else _over(_1_0, f_)
|
|
2207
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f) # PYCHOK type
|
|
2179
2208
|
|
|
2180
2209
|
|
|
2181
2210
|
def f2f_(f):
|
|
@@ -2185,11 +2214,11 @@ def f2f_(f):
|
|
|
2185
2214
|
|
|
2186
2215
|
@return: The inverse flattening (C{scalar} or C{0}), M{1 / f}.
|
|
2187
2216
|
|
|
2188
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2189
|
-
|
|
2217
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2218
|
+
for I{near-spherical} ellipsoids.
|
|
2190
2219
|
'''
|
|
2191
|
-
f_ = 0 if
|
|
2192
|
-
return _f__0_0 if
|
|
2220
|
+
f_ = 0 if _ispherical_f(f) else _over(_1_0, f)
|
|
2221
|
+
return _f__0_0 if _ispherical_f_(f_) else Float(f_=f_) # PYCHOK type
|
|
2193
2222
|
|
|
2194
2223
|
|
|
2195
2224
|
def f2f2(f):
|
|
@@ -2199,16 +2228,16 @@ def f2f2(f):
|
|
|
2199
2228
|
|
|
2200
2229
|
@return: The I{signed}, 2nd flattening (C{scalar} or C{INF}), M{f / (1 - f)}.
|
|
2201
2230
|
|
|
2202
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2203
|
-
|
|
2231
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2232
|
+
for I{near-spherical} ellipsoids.
|
|
2204
2233
|
|
|
2205
2234
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2206
2235
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2207
2236
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2208
2237
|
'''
|
|
2209
2238
|
t = _1_0 - f
|
|
2210
|
-
return Float(f2=_0_0 if
|
|
2211
|
-
|
|
2239
|
+
return Float(f2=_0_0 if _ispherical_f(f) else
|
|
2240
|
+
(INF if fabs(t) < EPS else _over(f, t))) # PYCHOK type
|
|
2212
2241
|
|
|
2213
2242
|
|
|
2214
2243
|
def f2n(f):
|
|
@@ -2219,14 +2248,14 @@ def f2n(f):
|
|
|
2219
2248
|
@return: The I{signed}, 3rd flattening (-1 <= C{float} < 1),
|
|
2220
2249
|
M{f / (2 - f)}.
|
|
2221
2250
|
|
|
2222
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2223
|
-
|
|
2251
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2252
|
+
for I{near-spherical} ellipsoids.
|
|
2224
2253
|
|
|
2225
2254
|
@see: U{Eccentricity conversions<https://GeographicLib.SourceForge.io/
|
|
2226
2255
|
C++/doc/classGeographicLib_1_1Ellipsoid.html>} and U{Flattening
|
|
2227
2256
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2228
2257
|
'''
|
|
2229
|
-
return Float(n=_0_0 if
|
|
2258
|
+
return Float(n=_0_0 if _ispherical_f(f) else _over(f, float(_2_0 - f)))
|
|
2230
2259
|
|
|
2231
2260
|
|
|
2232
2261
|
def n2e2(n):
|
|
@@ -2237,14 +2266,14 @@ def n2e2(n):
|
|
|
2237
2266
|
@return: The I{signed}, (1st) eccentricity I{squared} (C{float} or NINF),
|
|
2238
2267
|
M{4 * n / (1 + n)**2}.
|
|
2239
2268
|
|
|
2240
|
-
@note: The result is positive for I{oblate}, negative for I{prolate}
|
|
2241
|
-
|
|
2269
|
+
@note: The result is positive for I{oblate}, negative for I{prolate} or C{0}
|
|
2270
|
+
for I{near-spherical} ellipsoids.
|
|
2242
2271
|
|
|
2243
2272
|
@see: U{Flattening<https://WikiPedia.org/wiki/Flattening>}.
|
|
2244
2273
|
'''
|
|
2245
2274
|
t = (n + _1_0)**2
|
|
2246
2275
|
return Float(e2=_0_0 if fabs(n) < EPS0 else
|
|
2247
|
-
(NINF if t < EPS0 else (_4_0 * n
|
|
2276
|
+
(NINF if t < EPS0 else _over(_4_0 * n, t)))
|
|
2248
2277
|
|
|
2249
2278
|
|
|
2250
2279
|
def n2f(n):
|
|
@@ -2259,8 +2288,8 @@ def n2f(n):
|
|
|
2259
2288
|
<https://WikiPedia.org/wiki/Flattening>}.
|
|
2260
2289
|
'''
|
|
2261
2290
|
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
|
|
2291
|
+
f = 0 if fabs(n) < EPS0 else (NINF if t < EPS0 else _over(_2_0 * n, t))
|
|
2292
|
+
return _f_0_0 if _ispherical_f(f) else Float(f=f)
|
|
2264
2293
|
|
|
2265
2294
|
|
|
2266
2295
|
def n2f_(n):
|
|
@@ -2369,7 +2398,7 @@ Ellipsoids._assert( # <https://WikiPedia.org/wiki/Earth_ellipsoid>
|
|
|
2369
2398
|
|
|
2370
2399
|
_EWGS84 = Ellipsoids.WGS84 # (INTERNAL) shared
|
|
2371
2400
|
|
|
2372
|
-
if __name__ ==
|
|
2401
|
+
if __name__ == _DMAIN_:
|
|
2373
2402
|
|
|
2374
2403
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
2375
2404
|
from pygeodesy import nameof, printf
|
|
@@ -2392,7 +2421,7 @@ if __name__ == '__main__':
|
|
|
2392
2421
|
t = [NN] + Ellipsoids.toRepr(all=True, asorted=True).split(_NL_)
|
|
2393
2422
|
printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
|
|
2394
2423
|
|
|
2395
|
-
# % python3 -m pygeodesy.ellipsoids
|
|
2424
|
+
# % python3.13 -m pygeodesy.ellipsoids
|
|
2396
2425
|
|
|
2397
2426
|
# 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
2427
|
# e=8.1819190842622e-02, f_=2.98257223563e+02, f=3.3528106647475e-03, n=1.6792203863837e-03 (0.0e+00)
|
|
@@ -2418,7 +2447,7 @@ if __name__ == '__main__':
|
|
|
2418
2447
|
# BetaKs 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
|
|
2419
2448
|
# KsOrder 8
|
|
2420
2449
|
|
|
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.
|
|
2450
|
+
# 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
2451
|
# e=8.2094437949696e-02, f_=-2.97257223563e+02, f=-3.3640898209765e-03, n=-1.6792203863837e-03 (0.0e+00)
|
|
2423
2452
|
# AlphaKs -0.00084149152514366627, 0.00000076653480614871, -0.00000000120934503389, 0.0000000000024576225, -0.00000000000000578863, 0.00000000000000001502, -0.00000000000000000004, 0.0
|
|
2424
2453
|
# BetaKs -0.00084149187224351817, 0.00000005842735196773, -0.0000000001680487236, 0.00000000000021706261, -0.00000000000000038002, 0.00000000000000000073, -0.0, 0.0
|