pygeodesy 24.6.1__py2.py3-none-any.whl → 24.6.24__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/METADATA +2 -2
- PyGeodesy-24.6.24.dist-info/RECORD +117 -0
- pygeodesy/__init__.py +33 -32
- pygeodesy/albers.py +2 -2
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/auxAngle.py +40 -39
- pygeodesy/auxilats/auxDLat.py +3 -2
- pygeodesy/auxilats/auxLat.py +16 -18
- pygeodesy/auxilats/auxily.py +1 -1
- pygeodesy/azimuthal.py +10 -10
- pygeodesy/basics.py +9 -1
- pygeodesy/booleans.py +53 -66
- pygeodesy/cartesianBase.py +143 -155
- pygeodesy/css.py +14 -18
- pygeodesy/datums.py +6 -6
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +16 -2
- pygeodesy/deprecated/datum.py +3 -3
- pygeodesy/deprecated/functions.py +6 -8
- pygeodesy/dms.py +23 -27
- pygeodesy/ecef.py +49 -55
- pygeodesy/elevations.py +4 -4
- pygeodesy/ellipsoidalBase.py +28 -70
- pygeodesy/ellipsoidalBaseDI.py +19 -23
- pygeodesy/ellipsoidalExact.py +3 -3
- pygeodesy/ellipsoidalGeodSolve.py +15 -23
- pygeodesy/ellipsoidalKarney.py +37 -60
- pygeodesy/ellipsoidalNvector.py +44 -50
- pygeodesy/ellipsoidalVincenty.py +11 -14
- pygeodesy/ellipsoids.py +107 -101
- pygeodesy/errors.py +101 -49
- pygeodesy/etm.py +32 -44
- pygeodesy/formy.py +55 -58
- pygeodesy/frechet.py +20 -23
- pygeodesy/fsums.py +4 -4
- pygeodesy/gars.py +3 -4
- pygeodesy/geodesici.py +909 -0
- pygeodesy/geodesicw.py +11 -13
- pygeodesy/geodesicx/__init__.py +4 -4
- pygeodesy/geodesicx/gx.py +18 -28
- pygeodesy/geodesicx/gxbases.py +20 -8
- pygeodesy/geodesicx/gxline.py +16 -22
- pygeodesy/geodsolve.py +102 -34
- pygeodesy/geohash.py +39 -60
- pygeodesy/geoids.py +28 -37
- pygeodesy/hausdorff.py +21 -23
- pygeodesy/heights.py +15 -28
- pygeodesy/internals.py +19 -12
- pygeodesy/interns.py +4 -10
- pygeodesy/iters.py +2 -2
- pygeodesy/karney.py +20 -4
- pygeodesy/ktm.py +13 -16
- pygeodesy/latlonBase.py +202 -191
- pygeodesy/lazily.py +96 -59
- pygeodesy/lcc.py +29 -32
- pygeodesy/ltp.py +43 -24
- pygeodesy/ltpTuples.py +190 -183
- pygeodesy/mgrs.py +35 -9
- pygeodesy/named.py +106 -72
- pygeodesy/namedTuples.py +43 -14
- pygeodesy/nvectorBase.py +23 -27
- pygeodesy/osgr.py +9 -9
- pygeodesy/points.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +5 -5
- pygeodesy/rhumb/bases.py +30 -31
- pygeodesy/rhumb/ekx.py +3 -4
- pygeodesy/rhumb/solve.py +8 -61
- pygeodesy/solveBase.py +22 -19
- pygeodesy/sphericalBase.py +26 -21
- pygeodesy/sphericalNvector.py +13 -13
- pygeodesy/sphericalTrigonometry.py +86 -97
- pygeodesy/streprs.py +8 -36
- pygeodesy/trf.py +3 -3
- pygeodesy/triaxials.py +117 -91
- pygeodesy/units.py +229 -321
- pygeodesy/unitsBase.py +116 -108
- pygeodesy/ups.py +26 -31
- pygeodesy/utily.py +12 -11
- pygeodesy/utm.py +35 -40
- pygeodesy/utmups.py +43 -46
- pygeodesy/utmupsBase.py +9 -10
- pygeodesy/vector3d.py +59 -62
- pygeodesy/vector3dBase.py +17 -15
- pygeodesy/webmercator.py +19 -21
- pygeodesy/wgrs.py +18 -20
- PyGeodesy-24.6.1.dist-info/RECORD +0 -116
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/top_level.txt +0 -0
pygeodesy/geodesicw.py
CHANGED
|
@@ -37,7 +37,7 @@ from contextlib import contextmanager
|
|
|
37
37
|
# from math import fabs # from .utily
|
|
38
38
|
|
|
39
39
|
__all__ = _ALL_LAZY.geodesicw
|
|
40
|
-
__version__ = '24.
|
|
40
|
+
__version__ = '24.06.24'
|
|
41
41
|
|
|
42
42
|
_plumb_ = 'plumb'
|
|
43
43
|
_TRIPS = 65
|
|
@@ -71,8 +71,8 @@ class _gWrapped(_kWrapped):
|
|
|
71
71
|
|
|
72
72
|
@arg a_ellipsoid: The equatorial radius I{a} (C{meter}, conventionally),
|
|
73
73
|
an ellipsoid (L{Ellipsoid}) or a datum (L{Datum}).
|
|
74
|
-
@arg f: The ellipsoid's flattening (C{scalar}),
|
|
75
|
-
is
|
|
74
|
+
@arg f: The ellipsoid's flattening (C{scalar}), required if B{C{a_ellipsoid})
|
|
75
|
+
is C{meter}, ignored otherwise.
|
|
76
76
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
77
77
|
'''
|
|
78
78
|
_earth_datum(self, a_ellipsoid, f=f, **name) # raiser=NN
|
|
@@ -429,17 +429,16 @@ class _gWrapped(_kWrapped):
|
|
|
429
429
|
_wrapped = _gWrapped() # PYCHOK singleton, .ellipsoids, .test/base.py
|
|
430
430
|
|
|
431
431
|
|
|
432
|
-
def Geodesic(a_ellipsoid, f=None, **name):
|
|
432
|
+
def Geodesic(a_ellipsoid=_EWGS84, f=None, **name):
|
|
433
433
|
'''Return a I{wrapped} C{geodesic.Geodesic} instance from I{Karney}'s
|
|
434
434
|
Python U{geographiclib<https://PyPI.org/project/geographiclib>},
|
|
435
435
|
provide the latter is installed, otherwise an C{ImportError}.
|
|
436
436
|
|
|
437
437
|
@arg a_ellipsoid: An ellipsoid (L{Ellipsoid}) or datum (L{Datum})
|
|
438
438
|
or the equatorial radius I{a} of the ellipsoid (C{meter}).
|
|
439
|
-
@arg f: The flattening of the ellipsoid (C{scalar}),
|
|
440
|
-
B{C{a_ellipsoid}}) is
|
|
441
|
-
@kwarg name: Optional
|
|
442
|
-
like B{C{f}}.
|
|
439
|
+
@arg f: The flattening of the ellipsoid (C{scalar}), required if
|
|
440
|
+
B{C{a_ellipsoid}}) is C{meter}, ignored otherwise.
|
|
441
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}), ignored like B{C{f}}.
|
|
443
442
|
'''
|
|
444
443
|
return _wrapped.Geodesic(a_ellipsoid, f=f, **name)
|
|
445
444
|
|
|
@@ -453,11 +452,10 @@ def GeodesicLine(geodesic, lat1, lon1, azi1, caps=Caps._STD_LINE):
|
|
|
453
452
|
@arg lat1: Latitude of the first points (C{degrees}).
|
|
454
453
|
@arg lon1: Longitude of the first points (C{degrees}).
|
|
455
454
|
@arg azi1: Azimuth at the first points (compass C{degrees360}).
|
|
456
|
-
@kwarg caps: Optional, bit-or'ed combination of L{Caps} values
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
and C{GeodesicLine.ArcPosition}.
|
|
455
|
+
@kwarg caps: Optional, bit-or'ed combination of L{Caps} values specifying
|
|
456
|
+
the capabilities the C{GeodesicLine} instance should possess,
|
|
457
|
+
i.e., which quantities can be returned by methods
|
|
458
|
+
C{GeodesicLine.Position} and C{GeodesicLine.ArcPosition}.
|
|
461
459
|
'''
|
|
462
460
|
return _wrapped.GeodesicLine(geodesic, lat1, lon1, azi1, caps=caps)
|
|
463
461
|
|
pygeodesy/geodesicx/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
u'''A pure Python version of I{Karney}'s C++ classes U{GeodesicExact
|
|
5
|
-
<https://GeographicLib.SourceForge.io/C++/classGeographicLib_1_1GeodesicExact.html>}
|
|
5
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>}
|
|
6
6
|
and U{GeodesicLineExact
|
|
7
7
|
<https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1GeodesicLine.html>}.
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ and the background information at U{Geodesics on an ellipsoid of revolution
|
|
|
13
13
|
|
|
14
14
|
Also, compare C{GeodesicExact} and C{GeodesicLineExact} to I{standard} classes C{Geodesic}
|
|
15
15
|
respectively C{GeodesicLine} from I{Karney}'s Python implementation U{geographiclib
|
|
16
|
-
<https://GeographicLib.SourceForge.io/C++/doc/other.html#python>}, see
|
|
17
|
-
L{pygeodesy.karney}.
|
|
16
|
+
<https://GeographicLib.SourceForge.io/C++/doc/other.html#python>}, see modules
|
|
17
|
+
L{pygeodesy.geodesicw} and L{pygeodesy.karney}.
|
|
18
18
|
'''
|
|
19
19
|
|
|
20
20
|
from pygeodesy.geodesicx.gx import GeodesicExact, GeodesicLineExact # PYCHOK exported
|
|
@@ -23,7 +23,7 @@ from pygeodesy.karney import Caps, GeodesicError
|
|
|
23
23
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY
|
|
24
24
|
|
|
25
25
|
__all__ = _ALL_LAZY.geodesicx + _ALL_DOCS(Caps, GeodesicError)
|
|
26
|
-
__version__ = '24.
|
|
26
|
+
__version__ = '24.06.19'
|
|
27
27
|
|
|
28
28
|
# **) MIT License
|
|
29
29
|
#
|
pygeodesy/geodesicx/gx.py
CHANGED
|
@@ -44,25 +44,26 @@ from pygeodesy.constants import EPS, EPS0, EPS02, MANT_DIG, NAN, PI, _EPSqrt, \
|
|
|
44
44
|
from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
45
45
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
46
46
|
from pygeodesy.errors import GeodesicError, _xkwds_pop2
|
|
47
|
-
from pygeodesy.fmath import hypot as _hypot
|
|
47
|
+
from pygeodesy.fmath import hypot as _hypot, Fmt
|
|
48
48
|
from pygeodesy.fsums import fsumf_, fsum1f_
|
|
49
49
|
from pygeodesy.geodesicx.gxbases import _cosSeries, _GeodesicBase, \
|
|
50
|
-
_sincos12, _sin1cos2,
|
|
51
|
-
|
|
52
|
-
from pygeodesy.
|
|
50
|
+
_sincos12, _sin1cos2, _sinf1cos2d, \
|
|
51
|
+
_TINY, _xnC4
|
|
52
|
+
from pygeodesy.geodesicx.gxline import _GeodesicLineExact, _update_glXs
|
|
53
|
+
from pygeodesy.interns import NN, _DOT_, _UNDER_
|
|
53
54
|
from pygeodesy.karney import GDict, _around, _atan2d, Caps, _cbrt, _diff182, \
|
|
54
55
|
_fix90, _K_2_0, _norm2, _norm180, _polynomial, \
|
|
55
56
|
_signBit, _sincos2, _sincos2d, _sincos2de, _unsigned2
|
|
56
57
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS
|
|
57
58
|
from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
|
|
58
59
|
from pygeodesy.props import deprecated_Property, Property, Property_RO, property_RO
|
|
59
|
-
from pygeodesy.streprs import Fmt
|
|
60
|
+
# from pygeodesy.streprs import Fmt # from .fmath
|
|
60
61
|
from pygeodesy.utily import atan2d as _atan2d_reverse, _unrollon, _Wrap, wrap360
|
|
61
62
|
|
|
62
63
|
from math import atan2, copysign, cos, degrees, fabs, radians, sqrt
|
|
63
64
|
|
|
64
65
|
__all__ = ()
|
|
65
|
-
__version__ = '24.
|
|
66
|
+
__version__ = '24.06.24'
|
|
66
67
|
|
|
67
68
|
_MAXIT1 = 20
|
|
68
69
|
_MAXIT2 = 10 + _MAXIT1 + MANT_DIG # MANT_DIG == C++ digits
|
|
@@ -553,10 +554,10 @@ class GeodesicExact(_GeodesicBase):
|
|
|
553
554
|
# to check, e.g., on verifying quadrants in atan2. In addition,
|
|
554
555
|
# this enforces some symmetries in the results returned.
|
|
555
556
|
|
|
556
|
-
# Initialize for the meridian. No longitude calculation is
|
|
557
|
-
#
|
|
558
|
-
sbet1, cbet1 =
|
|
559
|
-
sbet2, cbet2 =
|
|
557
|
+
# Initialize for the meridian. No longitude calculation is done in
|
|
558
|
+
# this case to let the parameter default to 0.
|
|
559
|
+
sbet1, cbet1 = _sinf1cos2d(lat1, self.f1)
|
|
560
|
+
sbet2, cbet2 = _sinf1cos2d(lat2, self.f1)
|
|
560
561
|
# If cbet1 < -sbet1, then cbet2 - cbet1 is a sensitive measure
|
|
561
562
|
# of the |bet1| - |bet2|. Alternatively (cbet1 >= -sbet1),
|
|
562
563
|
# abs(sbet2) + sbet1 is a better measure. This logic is used
|
|
@@ -1241,27 +1242,16 @@ class GeodesicExact(_GeodesicBase):
|
|
|
1241
1242
|
|
|
1242
1243
|
Polygon = Area # for C{geographiclib} compatibility
|
|
1243
1244
|
|
|
1244
|
-
def
|
|
1245
|
-
'''(INTERNAL) Helper, also for C{_G_GeodesicLineExact}.
|
|
1246
|
-
'''
|
|
1247
|
-
sbet, cbet = _sincos2d(lat)
|
|
1248
|
-
# ensure cbet1 = +epsilon at poles; doing the fix on beta means
|
|
1249
|
-
# that sig12 will be <= 2*tiny for two points at the same pole
|
|
1250
|
-
sbet, cbet = _norm2(sbet * self.f1, cbet)
|
|
1251
|
-
return sbet, (cbet if fabs(cbet) > _TINY else _TINY)
|
|
1252
|
-
|
|
1253
|
-
def toStr(self, prec=6, sep=_COMMASPACE_, **unused): # PYCHOK signature
|
|
1245
|
+
def toStr(self, **prec_sep_name): # PYCHOK signature
|
|
1254
1246
|
'''Return this C{GeodesicExact} as string.
|
|
1255
1247
|
|
|
1256
|
-
@
|
|
1257
|
-
|
|
1258
|
-
of 1 and above, but kept for negative B{C{prec}} values.
|
|
1259
|
-
@kwarg sep: Separator to join (C{str}).
|
|
1248
|
+
@see: L{Ellipsoid.toStr<pygeodesy.ellipsoids.Ellipsoid.toStr>}
|
|
1249
|
+
for further details.
|
|
1260
1250
|
|
|
1261
|
-
@return:
|
|
1251
|
+
@return: C{GeodesicExact} (C{str}).
|
|
1262
1252
|
'''
|
|
1263
|
-
|
|
1264
|
-
|
|
1253
|
+
return self._instr(props=(GeodesicExact.ellipsoid,),
|
|
1254
|
+
C4order=self.C4order, **prec_sep_name)
|
|
1265
1255
|
|
|
1266
1256
|
|
|
1267
1257
|
class GeodesicLineExact(_GeodesicLineExact):
|
|
@@ -1290,7 +1280,7 @@ class GeodesicLineExact(_GeodesicLineExact):
|
|
|
1290
1280
|
'''
|
|
1291
1281
|
_xinstanceof(GeodesicExact, geodesic=geodesic)
|
|
1292
1282
|
if (caps & Caps.LINE_OFF): # copy to avoid updates
|
|
1293
|
-
geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name))
|
|
1283
|
+
geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name))
|
|
1294
1284
|
# _update_all(geodesic)
|
|
1295
1285
|
_GeodesicLineExact.__init__(self, geodesic, lat1, lon1, azi1, caps, 0, **name)
|
|
1296
1286
|
|
pygeodesy/geodesicx/gxbases.py
CHANGED
|
@@ -9,19 +9,21 @@ U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
|
9
9
|
'''
|
|
10
10
|
|
|
11
11
|
from pygeodesy.basics import isodd, _MODS
|
|
12
|
-
from pygeodesy.constants import _0_0, _100_0
|
|
12
|
+
from pygeodesy.constants import _EPSmin as _TINY, _0_0, _100_0
|
|
13
13
|
from pygeodesy.errors import _or, _xkwds_item2
|
|
14
14
|
from pygeodesy.fmath import hypot as _hypot
|
|
15
|
-
from pygeodesy.karney import _CapsBase, GeodesicError, _2cos2x,
|
|
15
|
+
from pygeodesy.karney import _CapsBase, GeodesicError, _2cos2x, \
|
|
16
|
+
_norm2, _sincos2d, _sum2_
|
|
16
17
|
# from pygeodesy.lazily import _MODS, printf # .basics, _MODS
|
|
17
18
|
|
|
18
|
-
from math import ldexp as _ldexp
|
|
19
|
+
from math import fabs, ldexp as _ldexp
|
|
19
20
|
|
|
20
21
|
__all__ = ()
|
|
21
|
-
__version__ = '24.
|
|
22
|
+
__version__ = '24.06.16'
|
|
22
23
|
|
|
23
24
|
# valid C{nC4}s and C{C4order}s, see _xnC4 below
|
|
24
25
|
_nC4s = {24: 2900, 27: 4032, 30: 5425}
|
|
26
|
+
# assert (_TINY * EPS) > 0 and (_TINY + EPS) == EPS # underflow guard
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
class _GeodesicBase(_CapsBase): # in .geodsolve
|
|
@@ -71,15 +73,15 @@ def _cosSeries(c4s, sx, cx): # PYCHOK shared .geodesicx.gx and -.gxline
|
|
|
71
73
|
y0 = t0 = y1 = t1 = _0_0
|
|
72
74
|
c4 = list(c4s)
|
|
73
75
|
_c4 = c4.pop
|
|
74
|
-
_s2 = _sum2_
|
|
75
76
|
if isodd(len(c4)):
|
|
76
77
|
y0 = _c4()
|
|
78
|
+
_s2 = _sum2_
|
|
77
79
|
while c4:
|
|
78
80
|
# y1 = ar * y0 - y1 + c4.pop()
|
|
79
81
|
# y0 = ar * y1 - y0 + c4.pop()
|
|
80
82
|
y1, t1 = _s2(ar * y0, ar * t0, -y1, -t1, _c4())
|
|
81
83
|
y0, t0 = _s2(ar * y1, ar * t1, -y0, -t0, _c4())
|
|
82
|
-
# s =
|
|
84
|
+
# s = (y0 - y1) * cx
|
|
83
85
|
s, _ = _s2(cx * y0, _0_0, cx * t0, -cx * y1, -cx * t1)
|
|
84
86
|
return s
|
|
85
87
|
|
|
@@ -93,7 +95,7 @@ def _f2(hi, lo): # in .geodesicx._C4_24, _27 and _30
|
|
|
93
95
|
return _ldexp(_f(hi), 52) + _f(lo)
|
|
94
96
|
|
|
95
97
|
|
|
96
|
-
def _sincos12(sin1, cos1, sin2, cos2, sineg0=False):
|
|
98
|
+
def _sincos12(sin1, cos1, sin2, cos2, sineg0=False):
|
|
97
99
|
'''(INTERNAL) Compute the sine and cosine of angle
|
|
98
100
|
M{ang12 = atan2(sin2, cos2) - atan2(sin1, cos1)}.
|
|
99
101
|
|
|
@@ -111,7 +113,7 @@ def _sincos12(sin1, cos1, sin2, cos2, sineg0=False): # PYCHOK shared
|
|
|
111
113
|
return s, c
|
|
112
114
|
|
|
113
115
|
|
|
114
|
-
def _sin1cos2(sin1, cos1, sin2, cos2):
|
|
116
|
+
def _sin1cos2(sin1, cos1, sin2, cos2):
|
|
115
117
|
'''(INTERNAL) Compute the C{sin1 * cos2} sine and its cosine.
|
|
116
118
|
|
|
117
119
|
@return: 2-Tuple C{(sin1 * cos2, hypot(sin1 * sin2, cos1)}.
|
|
@@ -121,6 +123,16 @@ def _sin1cos2(sin1, cos1, sin2, cos2): # PYCHOK shared
|
|
|
121
123
|
return s, c # _norm2(s, c)
|
|
122
124
|
|
|
123
125
|
|
|
126
|
+
def _sinf1cos2d(lat, f1):
|
|
127
|
+
'''(INTERNAL) See C{GeodesicExact} and C{_GeodesicLineExact}.
|
|
128
|
+
'''
|
|
129
|
+
sbet, cbet = _sincos2d(lat)
|
|
130
|
+
# ensure cbet1 = +epsilon at poles; doing the fix on beta means
|
|
131
|
+
# that sig12 will be <= 2*tiny for two points at the same pole
|
|
132
|
+
sbet, cbet = _norm2(sbet * f1, cbet)
|
|
133
|
+
return sbet, (cbet if fabs(cbet) > _TINY else _TINY)
|
|
134
|
+
|
|
135
|
+
|
|
124
136
|
def _xnC4(**name_nC4):
|
|
125
137
|
'''(INTERNAL) Validate C{C4order}.
|
|
126
138
|
'''
|
pygeodesy/geodesicx/gxline.py
CHANGED
|
@@ -37,30 +37,27 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
37
37
|
# - s and c prefixes mean sin and cos
|
|
38
38
|
|
|
39
39
|
# from pygeodesy.basics import _xinstanceof # _MODS
|
|
40
|
-
from pygeodesy.constants import NAN,
|
|
41
|
-
|
|
42
|
-
from pygeodesy.errors import _xError
|
|
40
|
+
from pygeodesy.constants import NAN, _EPSqrt as _TOL, _0_0, _1_0, \
|
|
41
|
+
_180_0, _2__PI, _copysign_1_0
|
|
42
|
+
# from pygeodesy.errors import _xError # _MODS
|
|
43
43
|
from pygeodesy.fsums import fsumf_, fsum1f_
|
|
44
44
|
from pygeodesy.geodesicx.gxbases import _cosSeries, _GeodesicBase, \
|
|
45
|
-
_sincos12, _sin1cos2
|
|
45
|
+
_sincos12, _sin1cos2, \
|
|
46
|
+
_sinf1cos2d, _TINY
|
|
46
47
|
# from pygeodesy.geodesicw import _Intersecant2 # _MODS
|
|
47
|
-
# from pygeodesy.interns import _COMMASPACE_ # from .errors
|
|
48
48
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS
|
|
49
49
|
from pygeodesy.karney import _around, _atan2d, Caps, GDict, _fix90, \
|
|
50
50
|
_K_2_0, _norm2, _norm180, _sincos2, _sincos2d
|
|
51
|
-
from pygeodesy.
|
|
52
|
-
# from pygeodesy.
|
|
51
|
+
from pygeodesy.named import Property_RO, _update_all
|
|
52
|
+
# from pygeodesy.props import Property_RO, _update_all # from .named
|
|
53
53
|
from pygeodesy.utily import atan2d as _atan2d_reverse, sincos2
|
|
54
54
|
|
|
55
55
|
from math import atan2, cos, degrees, fabs, floor, radians, sin
|
|
56
56
|
|
|
57
57
|
__all__ = ()
|
|
58
|
-
__version__ = '24.
|
|
58
|
+
__version__ = '24.06.24'
|
|
59
59
|
|
|
60
60
|
_glXs = [] # instances of C{[_]GeodesicLineExact} to be updated
|
|
61
|
-
# underflow guard, we require _TINY * EPS > 0, _TINY + EPS == EPS
|
|
62
|
-
_TINY = _EPSmin
|
|
63
|
-
# assert (_TINY * EPS) > 0 and (_TINY + EPS) == EPS
|
|
64
61
|
|
|
65
62
|
|
|
66
63
|
def _update_glXs(gX): # see GeodesicExact.C4order and -._ef_reset_k2
|
|
@@ -122,7 +119,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
122
119
|
# allow lat, azimuth and unrolling of lon
|
|
123
120
|
self._caps = caps | Cs._LINE
|
|
124
121
|
|
|
125
|
-
sbet1, cbet1 =
|
|
122
|
+
sbet1, cbet1 = _sinf1cos2d(_around(lat1), gX.f1)
|
|
126
123
|
self._dn1 = gX._dn(sbet1, cbet1)
|
|
127
124
|
# Evaluate alp0 from sin(alp1) * cos(bet1) = sin(alp0), with alp0
|
|
128
125
|
# in [0, pi/2 - |bet1|]. Alt: calp0 = hypot(sbet1, calp1 * cbet1),
|
|
@@ -501,7 +498,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
501
498
|
try:
|
|
502
499
|
return _MODS.geodesicw._Intersecant2(self, lat0, lon0, radius, tol=tol)
|
|
503
500
|
except (TypeError, ValueError) as x:
|
|
504
|
-
raise _xError(x, lat0, lon0, radius, tol=_TOL)
|
|
501
|
+
raise _MODS.errors._xError(x, lat0, lon0, radius, tol=_TOL)
|
|
505
502
|
|
|
506
503
|
@Property_RO
|
|
507
504
|
def _H0e2_f1(self):
|
|
@@ -626,20 +623,17 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
626
623
|
# unnecessary because Einv inverts E
|
|
627
624
|
# return -self._eF.deltaEinv(stau1, ctau1)
|
|
628
625
|
|
|
629
|
-
def toStr(self,
|
|
626
|
+
def toStr(self, **prec_sep_name): # PYCHOK signature
|
|
630
627
|
'''Return this C{GeodesicLineExact} as string.
|
|
631
628
|
|
|
632
|
-
@
|
|
633
|
-
|
|
634
|
-
of 1 and above, but kept for negative B{C{prec}} values.
|
|
635
|
-
@kwarg sep: Separator to join (C{str}).
|
|
629
|
+
@see: L{Ellipsoid.toStr<pygeodesy.ellipsoids.Ellipsoid.toStr>}
|
|
630
|
+
for further details.
|
|
636
631
|
|
|
637
632
|
@return: C{GeodesicLineExact} (C{str}).
|
|
638
633
|
'''
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
return sep.join(_MODS.streprs.pairs(d, prec=prec))
|
|
634
|
+
C = _GeodesicLineExact
|
|
635
|
+
t = C.lat1, C.lon1, C.azi1, C.a13, C.s13, C.geodesic
|
|
636
|
+
return self._instr(props=t, **prec_sep_name)
|
|
643
637
|
|
|
644
638
|
|
|
645
639
|
__all__ += _ALL_DOCS(_GeodesicLineExact)
|
pygeodesy/geodsolve.py
CHANGED
|
@@ -10,30 +10,32 @@ of the C{GeodSolve} executable.
|
|
|
10
10
|
'''
|
|
11
11
|
|
|
12
12
|
from pygeodesy.basics import _xinstanceof
|
|
13
|
+
# from pygeodesy.constants import NAN, _0_0 # from .karney
|
|
13
14
|
# from pygeodesy.geodesicx import GeodesicAreaExact # _MODS
|
|
14
15
|
from pygeodesy.interns import NN, _a12_, _azi1_, _azi2_, \
|
|
15
16
|
_lat1_, _lat2_, _lon1_, _lon2_, _m12_, \
|
|
16
17
|
_M12_, _M21_, _s12_, _S12_, _UNDER_
|
|
17
18
|
from pygeodesy.interns import _UNUSED_, _not_ # PYCHOK used!
|
|
18
19
|
from pygeodesy.karney import _Azi, Caps, _Deg, GeodesicError, _GTuple, \
|
|
19
|
-
_Pass, _Lat, _Lon, _M, _M2, _sincos2d
|
|
20
|
+
_Pass, _Lat, _Lon, _M, _M2, _sincos2d, \
|
|
21
|
+
_0_0, NAN
|
|
20
22
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
21
23
|
_getenv, _PYGEODESY_GEODSOLVE_
|
|
22
24
|
from pygeodesy.named import _name1__
|
|
23
25
|
from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
|
|
24
|
-
from pygeodesy.props import Property, Property_RO
|
|
26
|
+
from pygeodesy.props import Property, Property_RO, property_RO
|
|
25
27
|
from pygeodesy.solveBase import _SolveBase, _SolveLineBase
|
|
26
28
|
from pygeodesy.utily import _unrollon, _Wrap, wrap360
|
|
27
29
|
|
|
28
30
|
__all__ = _ALL_LAZY.geodsolve
|
|
29
|
-
__version__ = '24.
|
|
31
|
+
__version__ = '24.06.26'
|
|
30
32
|
|
|
31
33
|
|
|
32
34
|
class GeodSolve12Tuple(_GTuple):
|
|
33
35
|
'''12-Tuple C{(lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12)} with
|
|
34
36
|
angles C{lat1}, C{lon1}, C{azi1}, C{lat2}, C{lon2} and C{azi2} and arc C{a12} all in
|
|
35
37
|
C{degrees}, initial C{azi1} and final C{azi2} forward azimuths, distance C{s12} and
|
|
36
|
-
reduced length C{m12} in C{meter}, area C{S12} in C{meter} I{squared}
|
|
38
|
+
reduced length C{m12} in C{meter}, area C{S12} in C{meter} I{squared} and geodesic
|
|
37
39
|
scale factors C{M12} and C{M21}, both C{scalar}, see U{GeodSolve
|
|
38
40
|
<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}.
|
|
39
41
|
'''
|
|
@@ -59,11 +61,11 @@ class _GeodesicSolveBase(_SolveBase):
|
|
|
59
61
|
def _cmdBasic(self):
|
|
60
62
|
'''(INTERNAL) Get the basic C{GeodSolve} cmd (C{tuple}).
|
|
61
63
|
'''
|
|
62
|
-
return (self.GeodSolve,) + self._b_option
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
return (self.GeodSolve, '-f') + (self._b_option +
|
|
65
|
+
self._e_option +
|
|
66
|
+
self._E_option +
|
|
67
|
+
self._p_option +
|
|
68
|
+
self._u_option)
|
|
67
69
|
|
|
68
70
|
@Property_RO
|
|
69
71
|
def _E_option(self):
|
|
@@ -222,8 +224,11 @@ class GeodesicSolve(_GeodesicSolveBase):
|
|
|
222
224
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>} and
|
|
223
225
|
Python U{Geodesic.InverseLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
224
226
|
'''
|
|
225
|
-
r
|
|
226
|
-
|
|
227
|
+
r = self.Inverse(lat1, lon1, lat2, lon2)
|
|
228
|
+
gl = GeodesicLineSolve(self, lat1, lon1, r.azi1, **_name1__(caps_name, _or_nameof=self))
|
|
229
|
+
gl._a13 = r.a12 # gl.SetArc(r.a12)
|
|
230
|
+
gl._s13 = r.s12 # gl.SetDistance(r.s12)
|
|
231
|
+
return gl
|
|
227
232
|
|
|
228
233
|
|
|
229
234
|
class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
@@ -237,6 +242,8 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
237
242
|
@note: This C{geodesic} is intended I{for testing purposes only}, it invokes the C{GeodSolve}
|
|
238
243
|
executable for I{every} method call.
|
|
239
244
|
'''
|
|
245
|
+
_a13 = \
|
|
246
|
+
_s13 = NAN # see GeodesicSolve._InverseLine
|
|
240
247
|
|
|
241
248
|
def __init__(self, geodesic, lat1, lon1, azi1, caps=Caps.ALL, **name):
|
|
242
249
|
'''New L{GeodesicLineSolve} instance, allowing points to be found along
|
|
@@ -268,7 +275,22 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
268
275
|
except GeodesicError:
|
|
269
276
|
pass
|
|
270
277
|
|
|
271
|
-
|
|
278
|
+
@Property_RO
|
|
279
|
+
def a13(self):
|
|
280
|
+
'''Get the arc length to reference point 3 (C{degrees}).
|
|
281
|
+
|
|
282
|
+
@see: Methods L{Arc} and L{SetArc}.
|
|
283
|
+
'''
|
|
284
|
+
return self._a13
|
|
285
|
+
|
|
286
|
+
def Arc(self):
|
|
287
|
+
'''Return the arc length to reference point 3 (C{degrees} or C{NAN}).
|
|
288
|
+
|
|
289
|
+
@see: Method L{SetArc} and property L{a13}.
|
|
290
|
+
'''
|
|
291
|
+
return self.a13
|
|
292
|
+
|
|
293
|
+
def ArcPosition(self, a12, outmask=Caps.STANDARD): # PYCHOK unused
|
|
272
294
|
'''Find the position on the line given B{C{a12}}.
|
|
273
295
|
|
|
274
296
|
@arg a12: Spherical arc length from the first point to the
|
|
@@ -277,7 +299,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
277
299
|
@return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
|
|
278
300
|
azi2, m12, a12, s12, M12, M21, S12}.
|
|
279
301
|
'''
|
|
280
|
-
return self._GDictInvoke(self._cmdArc, True, self._Names_Direct, a12)
|
|
302
|
+
return self._GDictInvoke(self._cmdArc, True, self._Names_Direct, a12)._unCaps(outmask)
|
|
281
303
|
|
|
282
304
|
@Property_RO
|
|
283
305
|
def azi1(self):
|
|
@@ -301,6 +323,17 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
301
323
|
'''
|
|
302
324
|
return self._cmdDistance + ('-a',)
|
|
303
325
|
|
|
326
|
+
def Distance(self):
|
|
327
|
+
'''Return the distance to reference point 3 (C{meter} or C{NAN}).
|
|
328
|
+
'''
|
|
329
|
+
return self.s13
|
|
330
|
+
|
|
331
|
+
@property_RO
|
|
332
|
+
def geodesic(self):
|
|
333
|
+
'''Get the geodesic (L{GeodesicSolve}).
|
|
334
|
+
'''
|
|
335
|
+
return self._solve # see .solveBase._SolveLineBase
|
|
336
|
+
|
|
304
337
|
def Intersecant2(self, lat0, lon0, radius, **kwds): # PYCHOK no cover
|
|
305
338
|
'''B{Not implemented}, throws a C{NotImplementedError} always.'''
|
|
306
339
|
self._notImplemented(lat0, lon0, radius, **kwds)
|
|
@@ -309,7 +342,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
309
342
|
'''B{Not implemented}, throws a C{NotImplementedError} always.'''
|
|
310
343
|
self._notImplemented(lat0, lon0, **kwds)
|
|
311
344
|
|
|
312
|
-
def Position(self, s12, outmask=
|
|
345
|
+
def Position(self, s12, outmask=Caps.STANDARD):
|
|
313
346
|
'''Find the position on the line given B{C{s12}}.
|
|
314
347
|
|
|
315
348
|
@arg s12: Distance from the first point to the second (C{meter}).
|
|
@@ -317,7 +350,44 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
317
350
|
@return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
|
|
318
351
|
azi2, m12, a12, s12, M12, M21, S12}, possibly C{a12=NAN}.
|
|
319
352
|
'''
|
|
320
|
-
return self._GDictInvoke(self._cmdDistance, True, self._Names_Direct, s12)
|
|
353
|
+
return self._GDictInvoke(self._cmdDistance, True, self._Names_Direct, s12)._unCaps(outmask)
|
|
354
|
+
|
|
355
|
+
@Property_RO
|
|
356
|
+
def s13(self):
|
|
357
|
+
'''Get the distance to reference point 3 (C{meter} or C{NAN}).
|
|
358
|
+
|
|
359
|
+
@see: Methods L{Distance} and L{SetDistance}.
|
|
360
|
+
'''
|
|
361
|
+
return self._s13
|
|
362
|
+
|
|
363
|
+
def SetArc(self, a13):
|
|
364
|
+
'''Set reference point 3 in terms relative to the first point.
|
|
365
|
+
|
|
366
|
+
@arg a13: Spherical arc length from the first to the reference
|
|
367
|
+
point (C{degrees}).
|
|
368
|
+
|
|
369
|
+
@return: The distance C{s13} (C{meter}) between the first and
|
|
370
|
+
the reference point or C{NAN}.
|
|
371
|
+
'''
|
|
372
|
+
if self._a13 != a13:
|
|
373
|
+
self._a13 = a13
|
|
374
|
+
self._s13 = self.ArcPosition(a13, outmask=Caps.DISTANCE).s12 # if a13 else _0_0
|
|
375
|
+
# _update_all(self)
|
|
376
|
+
return self._s13
|
|
377
|
+
|
|
378
|
+
def SetDistance(self, s13):
|
|
379
|
+
'''Set reference point 3 in terms relative to the first point.
|
|
380
|
+
|
|
381
|
+
@arg s13: Distance from the first to the reference point (C{meter}).
|
|
382
|
+
|
|
383
|
+
@return: The arc length C{a13} (C{degrees}) between the first
|
|
384
|
+
and the reference point or C{NAN}.
|
|
385
|
+
'''
|
|
386
|
+
if self._s13 != s13:
|
|
387
|
+
self._s13 = s13
|
|
388
|
+
self._a13 = self.Position(s13, outmask=Caps.DISTANCE).a12 if s13 else _0_0
|
|
389
|
+
# _update_all(self)
|
|
390
|
+
return self._a13 # NAN for GeodesicLineExact without Cap.DISTANCE_IN
|
|
321
391
|
|
|
322
392
|
def toStr(self, **prec_sep): # PYCHOK signature
|
|
323
393
|
'''Return this C{GeodesicLineSolve} as string.
|
|
@@ -362,49 +432,47 @@ if __name__ == '__main__':
|
|
|
362
432
|
p = glS.ArcPosition(49.475527)
|
|
363
433
|
printf('ArcPosition: %s %r', p == r, p)
|
|
364
434
|
|
|
365
|
-
# % python3 -m pygeodesy.geodsolve
|
|
366
435
|
|
|
367
|
-
#
|
|
436
|
+
# % python3 -m pygeodesy.geodsolve
|
|
368
437
|
|
|
369
|
-
# version: /opt/local/bin/GeodSolve: GeographicLib version
|
|
438
|
+
# version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
|
|
370
439
|
|
|
371
|
-
# Direct: GDict(
|
|
440
|
+
# Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
|
|
372
441
|
# Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
|
|
373
442
|
|
|
374
|
-
# Inverse: GDict(
|
|
443
|
+
# Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
|
|
375
444
|
# Inverse1: 49.94131021789904
|
|
376
445
|
# Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
|
|
377
446
|
|
|
378
|
-
# Position: True GDict(
|
|
379
|
-
# ArcPosition: False GDict(
|
|
447
|
+
# Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
|
|
448
|
+
# ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
|
|
380
449
|
|
|
381
450
|
|
|
382
451
|
# % python3 -m pygeodesy.geodsolve --verbose
|
|
383
452
|
|
|
384
453
|
# GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve --version (invoke)
|
|
385
|
-
# GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve: GeographicLib version
|
|
386
|
-
# version: /opt/local/bin/GeodSolve: GeographicLib version
|
|
387
|
-
# GeodesicSolve 'Test' 2: /opt/local/bin/GeodSolve -E -p 10
|
|
454
|
+
# GeodesicSolve 'Test' 1: /opt/local/bin/GeodSolve: GeographicLib version 2.2 (0)
|
|
455
|
+
# version: /opt/local/bin/GeodSolve: GeographicLib version 2.2
|
|
456
|
+
# GeodesicSolve 'Test' 2: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
|
|
388
457
|
# GeodesicSolve 'Test' 2: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
|
|
389
458
|
|
|
390
|
-
# Direct: GDict(
|
|
391
|
-
# GeodesicSolve 'Test' 3: /opt/local/bin/GeodSolve -E -p 10
|
|
459
|
+
# Direct: GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
|
|
460
|
+
# GeodesicSolve 'Test' 3: /opt/local/bin/GeodSolve -f -E -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
|
|
392
461
|
# GeodesicSolve 'Test' 3: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.0, lat2=51.884564505606761, lon2=-1.141172861200829, azi2=107.189397162605886, s12=5500000.0, a12=49.475527463251467, m12=4844148.703101486, M12=0.65091056699808603, M21=0.65122865892196558, S12=39735075134877.094 (0)
|
|
393
462
|
# Direct3: Destination3Tuple(lat=51.884565, lon=-1.141173, final=107.189397)
|
|
394
|
-
# GeodesicSolve 'Test' 4: /opt/local/bin/GeodSolve -E -p 10 -
|
|
463
|
+
# GeodesicSolve 'Test' 4: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
|
|
395
464
|
# GeodesicSolve 'Test' 4: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
|
|
396
465
|
|
|
397
|
-
# Inverse: GDict(
|
|
398
|
-
# GeodesicSolve 'Test' 5: /opt/local/bin/GeodSolve -E -p 10 -
|
|
466
|
+
# Inverse: GDict(a12=49.94131, azi1=51.198883, azi2=107.821777, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, m12=4877684.602706, M12=0.64473, M21=0.645046, s12=5551759.400319, S12=40041368848742.53125)
|
|
467
|
+
# GeodesicSolve 'Test' 5: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
|
|
399
468
|
# GeodesicSolve 'Test' 5: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
|
|
400
469
|
# Inverse1: 49.94131021789904
|
|
401
|
-
# GeodesicSolve 'Test' 6: /opt/local/bin/GeodSolve -E -p 10 -
|
|
470
|
+
# GeodesicSolve 'Test' 6: /opt/local/bin/GeodSolve -f -E -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
|
|
402
471
|
# GeodesicSolve 'Test' 6: lat1=40.600000000000001, lon1=-73.799999999999997, azi1=51.198882845579824, lat2=51.600000000000001, lon2=-0.5, azi2=107.821776735514248, s12=5551759.4003186841, a12=49.941310217899037, m12=4877684.6027061976, M12=0.64472969205948238, M21=0.64504567852134398, S12=40041368848742.531 (0)
|
|
403
472
|
# Inverse3: Distance3Tuple(distance=5551759.400319, initial=51.198883, final=107.821777)
|
|
404
473
|
|
|
405
|
-
# Position: True GDict(
|
|
406
|
-
# ArcPosition: False GDict(
|
|
407
|
-
|
|
474
|
+
# Position: True GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141173, m12=4844148.703101, M12=0.650911, M21=0.651229, s12=5500000.0, S12=39735075134877.09375)
|
|
475
|
+
# ArcPosition: False GDict(a12=49.475527, azi1=51.0, azi2=107.189397, lat1=40.6, lat2=51.884565, lon1=-73.8, lon2=-1.141174, m12=4844148.669561, M12=0.650911, M21=0.651229, s12=5499999.948497, S12=39735074737272.734375)
|
|
408
476
|
|
|
409
477
|
# **) MIT License
|
|
410
478
|
#
|