pygeodesy 24.6.24__py2.py3-none-any.whl → 24.7.7__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.24.dist-info → PyGeodesy-24.7.7.dist-info}/METADATA +2 -2
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/RECORD +23 -23
- pygeodesy/__init__.py +7 -1
- pygeodesy/__main__.py +6 -1
- pygeodesy/basics.py +8 -4
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +10 -3
- pygeodesy/errors.py +10 -1
- pygeodesy/geodesici.py +1111 -324
- pygeodesy/geodesicw.py +5 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/gx.py +19 -30
- pygeodesy/geodesicx/gxline.py +83 -72
- pygeodesy/geodsolve.py +36 -57
- pygeodesy/internals.py +40 -13
- pygeodesy/karney.py +63 -16
- pygeodesy/lazily.py +23 -21
- pygeodesy/ltpTuples.py +4 -4
- pygeodesy/rhumb/solve.py +21 -22
- pygeodesy/solveBase.py +177 -123
- pygeodesy/units.py +5 -5
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.7.dist-info}/top_level.txt +0 -0
pygeodesy/geodesicw.py
CHANGED
|
@@ -23,7 +23,7 @@ from pygeodesy.fsums import Fsum, Fmt, unstr
|
|
|
23
23
|
from pygeodesy.internals import _dunder_nameof, _under
|
|
24
24
|
from pygeodesy.interns import NN, _DOT_, _SPACE_, _to_, _too_
|
|
25
25
|
from pygeodesy.karney import _atan2d, Caps, Direct9Tuple, GDict, \
|
|
26
|
-
|
|
26
|
+
Inverse10Tuple, _kWrapped, _llz2line
|
|
27
27
|
from pygeodesy.latlonBase import LatLonBase as _LLB, F_D, Radius_
|
|
28
28
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
29
29
|
from pygeodesy.named import callername, classname, _name1__, _name2__
|
|
@@ -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.07.09'
|
|
41
41
|
|
|
42
42
|
_plumb_ = 'plumb'
|
|
43
43
|
_TRIPS = 65
|
|
@@ -220,7 +220,9 @@ class _gWrapped(_kWrapped):
|
|
|
220
220
|
'''
|
|
221
221
|
with _wargs(self, lat1, lon1, lat2, lon2, caps, **name) as args:
|
|
222
222
|
t = _Geodesic.InverseLine(self, *args)
|
|
223
|
-
|
|
223
|
+
gl = self._Line13(t, **name)
|
|
224
|
+
p2 = gl.Position(gl.s13, outmask=Caps.AZIMUTH)
|
|
225
|
+
return _llz2line(gl, lat2=lat2, lon2=lon2, azi2=p2.azi2)
|
|
224
226
|
|
|
225
227
|
def Line(self, lat1, lon1, azi1, caps=Caps._STD_LINE, **name):
|
|
226
228
|
'''Set up a I{wrapped} C{GeodesicLine} to compute several points
|
pygeodesy/geodesicx/__init__.py
CHANGED
pygeodesy/geodesicx/gx.py
CHANGED
|
@@ -63,7 +63,7 @@ from pygeodesy.utily import atan2d as _atan2d_reverse, _unrollon, _Wrap, wrap360
|
|
|
63
63
|
from math import atan2, copysign, cos, degrees, fabs, radians, sqrt
|
|
64
64
|
|
|
65
65
|
__all__ = ()
|
|
66
|
-
__version__ = '24.
|
|
66
|
+
__version__ = '24.07.09'
|
|
67
67
|
|
|
68
68
|
_MAXIT1 = 20
|
|
69
69
|
_MAXIT2 = 10 + _MAXIT1 + MANT_DIG # MANT_DIG == C++ digits
|
|
@@ -212,7 +212,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
212
212
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>} and
|
|
213
213
|
Python U{Geodesic.ArcDirectLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
214
214
|
'''
|
|
215
|
-
return self
|
|
215
|
+
return GeodesicLineExact(self, lat1, lon1, azi1, caps=caps, **name)._GenSet(self._debug, a12=a12)
|
|
216
216
|
|
|
217
217
|
def Area(self, polyline=False, **name):
|
|
218
218
|
'''Set up a L{GeodesicAreaExact} to compute area and
|
|
@@ -390,7 +390,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
390
390
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>} and
|
|
391
391
|
Python U{Geodesic.DirectLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
392
392
|
'''
|
|
393
|
-
return self
|
|
393
|
+
return GeodesicLineExact(self, lat1, lon1, azi1, caps=caps, **name)._GenSet(self._debug, s12=s12)
|
|
394
394
|
|
|
395
395
|
def _dn(self, sbet, cbet): # in gxline._GeodesicLineExact.__init__
|
|
396
396
|
'''(INTERNAL) Helper.
|
|
@@ -497,7 +497,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
497
497
|
Cs = Caps
|
|
498
498
|
if self._debug: # PYCHOK no cover
|
|
499
499
|
outmask |= Cs._DEBUG_INVERSE & self._debug
|
|
500
|
-
outmask &= Cs._OUT_MASK # incl.
|
|
500
|
+
outmask &= Cs._OUT_MASK # incl. _S_CALPs_ and _DEBUG_
|
|
501
501
|
# compute longitude difference carefully (with _diff182):
|
|
502
502
|
# result is in [-180, +180] but -180 is only for west-going
|
|
503
503
|
# geodesics, +180 is for east-going and meridional geodesics
|
|
@@ -505,8 +505,10 @@ class GeodesicExact(_GeodesicBase):
|
|
|
505
505
|
# see C{result} from geographiclib.geodesic.Inverse
|
|
506
506
|
if (outmask & Cs.LONG_UNROLL): # == (lon1 + lon12) + lon12s
|
|
507
507
|
r = GDict(lon1=lon1, lon2=fsumf_(lon1, lon12, lon12s))
|
|
508
|
-
|
|
508
|
+
elif (outmask & Cs.LONGITUDE):
|
|
509
509
|
r = GDict(lon1=_norm180(lon1), lon2=_norm180(lon2))
|
|
510
|
+
else:
|
|
511
|
+
r = GDict()
|
|
510
512
|
if _K_2_0: # GeographicLib 2.0
|
|
511
513
|
# make longitude difference positive
|
|
512
514
|
lon12, lon_ = _unsigned2(lon12)
|
|
@@ -535,7 +537,8 @@ class GeodesicExact(_GeodesicBase):
|
|
|
535
537
|
# If really close to the equator, treat as on equator.
|
|
536
538
|
lat1 = _around(_fix90(lat1))
|
|
537
539
|
lat2 = _around(_fix90(lat2))
|
|
538
|
-
|
|
540
|
+
if (outmask & Cs.LATITUDE):
|
|
541
|
+
r.set_(lat1=lat1, lat2=lat2)
|
|
539
542
|
# Swap points so that point with higher (abs) latitude is
|
|
540
543
|
# point 1. If one latitude is a NAN, then it becomes lat1.
|
|
541
544
|
swap_ = fabs(lat1) < fabs(lat2) or isnan(lat2)
|
|
@@ -671,7 +674,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
671
674
|
S12 = -S12
|
|
672
675
|
r.set_(S12=unsigned0(S12))
|
|
673
676
|
|
|
674
|
-
if (outmask & (Cs.AZIMUTH | Cs.
|
|
677
|
+
if (outmask & (Cs.AZIMUTH | Cs._S_CALPs_)):
|
|
675
678
|
if swap_:
|
|
676
679
|
salp1, salp2 = salp2, salp1
|
|
677
680
|
calp1, calp2 = calp2, calp1
|
|
@@ -683,7 +686,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
683
686
|
if (outmask & Cs.AZIMUTH):
|
|
684
687
|
r.set_(azi1=_atan2d(salp1, calp1),
|
|
685
688
|
azi2=_atan2d_reverse(salp2, calp2, reverse=outmask & Cs.REVERSE2))
|
|
686
|
-
if (outmask & Cs.
|
|
689
|
+
if (outmask & Cs._S_CALPs_):
|
|
687
690
|
r.set_(salp1=salp1, calp1=calp1,
|
|
688
691
|
salp2=salp2, calp2=calp2)
|
|
689
692
|
|
|
@@ -707,25 +710,13 @@ class GeodesicExact(_GeodesicBase):
|
|
|
707
710
|
r = self._GDictDirect(lat1, lon1, azi1, arcmode, s12_a12, outmask)
|
|
708
711
|
return r.toDirect9Tuple()
|
|
709
712
|
|
|
710
|
-
def _GenDirectLine(self, lat1, lon1, azi1, arcmode, s12_a12, caps, **name):
|
|
711
|
-
'''(INTERNAL) Helper for C{ArcDirectLine} and C{DirectLine}.
|
|
712
|
-
|
|
713
|
-
@return: A L{GeodesicLineExact} instance.
|
|
714
|
-
'''
|
|
715
|
-
azi1 = _norm180(azi1)
|
|
716
|
-
# guard against underflow in salp0. Also -0 is converted to +0.
|
|
717
|
-
s, c = _sincos2d(_around(azi1))
|
|
718
|
-
C = caps if arcmode else (caps | Caps.DISTANCE_IN)
|
|
719
|
-
return _GeodesicLineExact(self, lat1, lon1, azi1, C,
|
|
720
|
-
self._debug, s, c, **name)._GenSet(arcmode, s12_a12)
|
|
721
|
-
|
|
722
713
|
def _GenInverse(self, lat1, lon1, lat2, lon2, outmask=Caps.STANDARD):
|
|
723
714
|
'''(INTERNAL) The general I{Inverse} geodesic calculation.
|
|
724
715
|
|
|
725
716
|
@return: L{Inverse10Tuple}C{(a12, s12, salp1, calp1, salp2, calp2,
|
|
726
717
|
m12, M12, M21, S12)}.
|
|
727
718
|
'''
|
|
728
|
-
r = self._GDictInverse(lat1, lon1, lat2, lon2, outmask | Caps.
|
|
719
|
+
r = self._GDictInverse(lat1, lon1, lat2, lon2, outmask | Caps._S_CALPs_)
|
|
729
720
|
return r.toInverse10Tuple()
|
|
730
721
|
|
|
731
722
|
def _Inverse(self, ll1, ll2, wrap, **outmask):
|
|
@@ -815,11 +806,9 @@ class GeodesicExact(_GeodesicBase):
|
|
|
815
806
|
Python U{Geodesic.InverseLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
816
807
|
'''
|
|
817
808
|
Cs = Caps
|
|
818
|
-
r = self._GDictInverse(lat1, lon1, lat2, lon2, Cs.
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
return _GeodesicLineExact(self, lat1, lon1, azi1, C, # ensure a12 is distance
|
|
822
|
-
self._debug, r.salp1, r.calp1, **name)._GenSet(True, r.a12)
|
|
809
|
+
r = self._GDictInverse(lat1, lon1, lat2, lon2, Cs.AZIMUTH | Cs.DISTANCE | Cs._S_CALPs_)
|
|
810
|
+
return GeodesicLineExact(self, lat1, lon1, None, caps=caps, _s_calp1=(r.salp1, r.calp1),
|
|
811
|
+
**name)._GenSet(self._debug, lat2=lat2, lon2=lon2, **r)
|
|
823
812
|
|
|
824
813
|
def _InverseArea(self, _meridian, salp1, calp1, # PYCHOK 9 args
|
|
825
814
|
salp2, calp2,
|
|
@@ -1130,7 +1119,7 @@ class GeodesicExact(_GeodesicBase):
|
|
|
1130
1119
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>}
|
|
1131
1120
|
and Python U{Geodesic.Line<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
1132
1121
|
'''
|
|
1133
|
-
return
|
|
1122
|
+
return GeodesicLineExact(self, lat1, lon1, azi1, caps=caps, **name)._GenSet(self._debug)
|
|
1134
1123
|
|
|
1135
1124
|
@Property_RO
|
|
1136
1125
|
def n(self):
|
|
@@ -1250,8 +1239,8 @@ class GeodesicExact(_GeodesicBase):
|
|
|
1250
1239
|
|
|
1251
1240
|
@return: C{GeodesicExact} (C{str}).
|
|
1252
1241
|
'''
|
|
1253
|
-
|
|
1254
|
-
|
|
1242
|
+
t = GeodesicExact.caps, GeodesicExact.ellipsoid
|
|
1243
|
+
return self._instr(props=t, C4order=self.C4order, **prec_sep_name)
|
|
1255
1244
|
|
|
1256
1245
|
|
|
1257
1246
|
class GeodesicLineExact(_GeodesicLineExact):
|
|
@@ -1282,7 +1271,7 @@ class GeodesicLineExact(_GeodesicLineExact):
|
|
|
1282
1271
|
if (caps & Caps.LINE_OFF): # copy to avoid updates
|
|
1283
1272
|
geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name))
|
|
1284
1273
|
# _update_all(geodesic)
|
|
1285
|
-
_GeodesicLineExact.__init__(self, geodesic, lat1, lon1, azi1, caps,
|
|
1274
|
+
_GeodesicLineExact.__init__(self, geodesic, lat1, lon1, azi1, caps, **name)
|
|
1286
1275
|
|
|
1287
1276
|
|
|
1288
1277
|
def _Astroid(x, y):
|
pygeodesy/geodesicx/gxline.py
CHANGED
|
@@ -38,8 +38,8 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
38
38
|
|
|
39
39
|
# from pygeodesy.basics import _xinstanceof # _MODS
|
|
40
40
|
from pygeodesy.constants import NAN, _EPSqrt as _TOL, _0_0, _1_0, \
|
|
41
|
-
_180_0, _2__PI, _copysign_1_0
|
|
42
|
-
|
|
41
|
+
_180_0, _2__PI, _copysign_1_0, isfinite
|
|
42
|
+
from pygeodesy.errors import _xError, _xkwds_pop2
|
|
43
43
|
from pygeodesy.fsums import fsumf_, fsum1f_
|
|
44
44
|
from pygeodesy.geodesicx.gxbases import _cosSeries, _GeodesicBase, \
|
|
45
45
|
_sincos12, _sin1cos2, \
|
|
@@ -47,7 +47,8 @@ from pygeodesy.geodesicx.gxbases import _cosSeries, _GeodesicBase, \
|
|
|
47
47
|
# from pygeodesy.geodesicw import _Intersecant2 # _MODS
|
|
48
48
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_MODS as _MODS
|
|
49
49
|
from pygeodesy.karney import _around, _atan2d, Caps, GDict, _fix90, \
|
|
50
|
-
_K_2_0, _norm2, _norm180,
|
|
50
|
+
_K_2_0, _llz2line, _norm2, _norm180, \
|
|
51
|
+
_sincos2, _sincos2d
|
|
51
52
|
from pygeodesy.named import Property_RO, _update_all
|
|
52
53
|
# from pygeodesy.props import Property_RO, _update_all # from .named
|
|
53
54
|
from pygeodesy.utily import atan2d as _atan2d_reverse, sincos2
|
|
@@ -55,7 +56,7 @@ from pygeodesy.utily import atan2d as _atan2d_reverse, sincos2
|
|
|
55
56
|
from math import atan2, cos, degrees, fabs, floor, radians, sin
|
|
56
57
|
|
|
57
58
|
__all__ = ()
|
|
58
|
-
__version__ = '24.
|
|
59
|
+
__version__ = '24.07.09'
|
|
59
60
|
|
|
60
61
|
_glXs = [] # instances of C{[_]GeodesicLineExact} to be updated
|
|
61
62
|
|
|
@@ -92,23 +93,18 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
92
93
|
# _somg1 = _comg1 = NAN
|
|
93
94
|
# _ssig1 = _csig1 = NAN
|
|
94
95
|
|
|
95
|
-
def __init__(self, gX, lat1, lon1, azi1, caps,
|
|
96
|
+
def __init__(self, gX, lat1, lon1, azi1, caps, **name_):
|
|
96
97
|
'''(INTERNAL) New C{[_]GeodesicLineExact} instance.
|
|
97
98
|
'''
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if salp1_calp1:
|
|
104
|
-
salp1, calp1 = salp1_calp1
|
|
105
|
-
else:
|
|
99
|
+
# _xGeodesicExact(gX=gX)
|
|
100
|
+
if azi1 is None: # see GeodesicExact.InverseLine
|
|
101
|
+
(salp1, calp1), name_ = _xkwds_pop2(name_, _s_calp1=(_0_0, _1_0))
|
|
102
|
+
azi1 = _atan2d(salp1, calp1)
|
|
103
|
+
else: # guard against salp0 underflow, convert -0 to +0
|
|
106
104
|
azi1 = _norm180(azi1)
|
|
107
|
-
# guard against salp0 underflow,
|
|
108
|
-
# also -0 is converted to +0
|
|
109
105
|
salp1, calp1 = _sincos2d(_around(azi1))
|
|
110
|
-
if
|
|
111
|
-
self.name =
|
|
106
|
+
if name_:
|
|
107
|
+
self.name = name_
|
|
112
108
|
|
|
113
109
|
self._gX = gX # GeodesicExact only
|
|
114
110
|
self._lat1 = lat1 = _fix90(lat1)
|
|
@@ -117,7 +113,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
117
113
|
self._salp1 = salp1
|
|
118
114
|
self._calp1 = calp1
|
|
119
115
|
# allow lat, azimuth and unrolling of lon
|
|
120
|
-
self._caps = caps |
|
|
116
|
+
self._caps = caps | Caps._LINE
|
|
121
117
|
|
|
122
118
|
sbet1, cbet1 = _sinf1cos2d(_around(lat1), gX.f1)
|
|
123
119
|
self._dn1 = gX._dn(sbet1, cbet1)
|
|
@@ -142,11 +138,11 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
142
138
|
self._ssig1, self._csig1 = _norm2(sbet1, c) # sig1 in (-pi, pi]
|
|
143
139
|
# _norm2(somg1, comg1) # no need to normalize!
|
|
144
140
|
# _norm2(schi1?, cchi1) # no need to normalize!
|
|
145
|
-
if not (caps &
|
|
141
|
+
if not (caps & Caps.LINE_OFF):
|
|
146
142
|
_glXs.append(self)
|
|
147
143
|
# no need to pre-compute other attrs based on _Caps.X. All are
|
|
148
|
-
# Property_RO's, computed once and cached/memoized until reset
|
|
149
|
-
#
|
|
144
|
+
# Property_RO's, computed once and cached/memoized until reset when
|
|
145
|
+
# arc, distance, C4order is changed or Elliptic function is reset.
|
|
150
146
|
|
|
151
147
|
def __del__(self): # XXX use weakref?
|
|
152
148
|
if _glXs: # may be empty or None
|
|
@@ -295,22 +291,18 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
295
291
|
C{lon1}, C{azi1} and arc length C{a12} always included,
|
|
296
292
|
except when C{a12=NAN}.
|
|
297
293
|
'''
|
|
298
|
-
|
|
299
|
-
r = GDict(a12=NAN, s12=NAN) # note both a12 and s12, always
|
|
300
|
-
if not (arcmode or self._caps_DISTANCE_IN): # PYCHOK no cover
|
|
301
|
-
return r # Uninitialized or impossible distance requested
|
|
302
|
-
|
|
303
294
|
Cs = Caps
|
|
304
|
-
if
|
|
305
|
-
outmask
|
|
306
|
-
outmask &= self._caps & Cs._OUT_MASK
|
|
307
|
-
|
|
295
|
+
if outmask:
|
|
296
|
+
outmask &= self._caps & Cs._OUT_MASK
|
|
308
297
|
eF = self._eF
|
|
309
298
|
gX = self.geodesic # ._gX
|
|
299
|
+
r = GDict(a12=NAN, s12=NAN) # both a12 and s12, always
|
|
310
300
|
|
|
311
|
-
if
|
|
312
|
-
#
|
|
313
|
-
|
|
301
|
+
if not isfinite(s12_a12):
|
|
302
|
+
# E2 = sig12 = ssig12 = csig12 = NAN
|
|
303
|
+
return r._toNAN(outmask)
|
|
304
|
+
elif arcmode: # s12_a12 is (spherical) arc length
|
|
305
|
+
r.set_(a12=s12_a12)
|
|
314
306
|
sig12 = radians(s12_a12)
|
|
315
307
|
if _K_2_0:
|
|
316
308
|
ssig12, csig12 = sincos2(sig12) # utily, no NEG0
|
|
@@ -319,31 +311,25 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
319
311
|
a -= floor(a / _180_0) * _180_0 # 0 <= 0 < 180
|
|
320
312
|
ssig12 = _0_0 if a == 0 else sin(sig12)
|
|
321
313
|
csig12 = _0_0 if a == 90 else cos(sig12)
|
|
322
|
-
|
|
314
|
+
E2 = _0_0
|
|
315
|
+
elif self._caps_DISTANCE_IN: # s12_a12 is distance
|
|
323
316
|
t = s12_a12 / self._E0b
|
|
324
317
|
s, c = _sincos2(t) # tau12
|
|
325
318
|
# tau2 = tau1 + tau12
|
|
326
319
|
E2 = -eF.deltaEinv(*_sincos12(-s, c, *self._stau1_ctau1))
|
|
327
320
|
sig12 = fsum1f_(self._E1, -E2, t) # == t - (E2 - E1)
|
|
328
321
|
ssig12, csig12 = _sincos2(sig12)
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
322
|
+
r.set_(a12=degrees(sig12))
|
|
323
|
+
else: # uninitialized or impossible distance requested
|
|
324
|
+
return r
|
|
332
325
|
|
|
333
326
|
# sig2 = sig1 + sig12
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
# cbet2 = hypot(salp0, calp0 * csig2). Alt:
|
|
338
|
-
# cbet2 = hypot(csig2, salp0 * ssig2)
|
|
339
|
-
sbet2, cbet2 = _sin1cos2(calp0, salp0, csig2, ssig2)
|
|
340
|
-
if cbet2 == 0: # salp0 = 0, csig2 = 0, break degeneracy
|
|
341
|
-
cbet2 = csig2 = _TINY
|
|
342
|
-
# tan(alp0) = cos(sig2) * tan(alp2)
|
|
343
|
-
salp2 = salp0
|
|
344
|
-
calp2 = calp0 * csig2 # no need to normalize
|
|
327
|
+
ssig1, csig1 = self._ssig1, self._csig1
|
|
328
|
+
ssig2, csig2 = t = _sincos12(-ssig12, csig12, ssig1, csig1)
|
|
329
|
+
dn2 = eF.fDelta(*t)
|
|
345
330
|
|
|
346
|
-
if (outmask &
|
|
331
|
+
if (outmask & Cs.DISTANCE):
|
|
332
|
+
outmask ^= Cs.DISTANCE
|
|
347
333
|
if arcmode: # or f_0_01
|
|
348
334
|
E2 = eF.deltaE(ssig2, csig2, dn2)
|
|
349
335
|
# AB1 = _E0 * (E2 - _E1)
|
|
@@ -355,10 +341,34 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
355
341
|
s12 = s12_a12
|
|
356
342
|
r.set_(s12=s12)
|
|
357
343
|
|
|
344
|
+
if not outmask: # all done, see ._GenSet
|
|
345
|
+
return r
|
|
346
|
+
|
|
347
|
+
if self._debug: # PYCHOK no cover
|
|
348
|
+
outmask |= self._debug & Cs._DEBUG_DIRECT_LINE
|
|
349
|
+
|
|
358
350
|
if (outmask & Cs._DEBUG_DIRECT_LINE): # PYCHOK no cover
|
|
359
351
|
r.set_(sig12=sig12, dn2=dn2, b=gX.b, e2=gX.e2, f1=gX.f1,
|
|
360
352
|
E0b=self._E0b, E1=self._E1, E2=E2, eFk2=eF.k2, eFa2=eF.alpha2)
|
|
361
353
|
|
|
354
|
+
# sin(bet2) = cos(alp0) * sin(sig2) and
|
|
355
|
+
# cbet2 = hypot(salp0, calp0 * csig2). Alt:
|
|
356
|
+
# cbet2 = hypot(csig2, salp0 * ssig2)
|
|
357
|
+
salp0, calp0 = self._salp0, self._calp0
|
|
358
|
+
sbet2, cbet2 = _sin1cos2(calp0, salp0, csig2, ssig2)
|
|
359
|
+
if cbet2 == 0: # salp0 = 0, csig2 = 0, break degeneracy
|
|
360
|
+
cbet2 = csig2 = _TINY
|
|
361
|
+
# tan(alp0) = cos(sig2) * tan(alp2)
|
|
362
|
+
salp2 = salp0
|
|
363
|
+
calp2 = calp0 * csig2 # no need to normalize
|
|
364
|
+
|
|
365
|
+
if (outmask & Cs.AZIMUTH):
|
|
366
|
+
r.set_(azi2=_atan2d_reverse(salp2, calp2,
|
|
367
|
+
reverse=outmask & Cs.REVERSE2))
|
|
368
|
+
|
|
369
|
+
if (outmask & Cs.LATITUDE):
|
|
370
|
+
r.set_(lat2=_atan2d(sbet2, gX.f1 * cbet2))
|
|
371
|
+
|
|
362
372
|
if (outmask & Cs.LONGITUDE):
|
|
363
373
|
schi1 = self._somg1
|
|
364
374
|
cchi1 = self._cchi1
|
|
@@ -372,7 +382,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
372
382
|
tchi2 = t * schi2
|
|
373
383
|
chi12 = t * fsum1f_(_a(ssig1, csig1), -_a(ssig2, csig2),
|
|
374
384
|
_a(tchi2, cchi2), -_a(tchi1, cchi1), sig12)
|
|
375
|
-
lon2
|
|
385
|
+
lon2 = self.lon1 + degrees(chi12 - lam12)
|
|
376
386
|
else:
|
|
377
387
|
chi12 = atan2(*_sincos12(schi1, cchi1, schi2, cchi2))
|
|
378
388
|
lon2 = _norm180(self._lon1_norm180 + _norm180(degrees(chi12 - lam12)))
|
|
@@ -381,12 +391,6 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
381
391
|
r.set_(ssig2=ssig2, chi12=chi12, H0e2_f1=self._H0e2_f1,
|
|
382
392
|
csig2=csig2, lam12=lam12, H1=self._H1)
|
|
383
393
|
|
|
384
|
-
if (outmask & Cs.LATITUDE):
|
|
385
|
-
r.set_(lat2=_atan2d(sbet2, gX.f1 * cbet2))
|
|
386
|
-
|
|
387
|
-
if (outmask & Cs.AZIMUTH):
|
|
388
|
-
r.set_(azi2=_atan2d_reverse(salp2, calp2, reverse=outmask & Cs.REVERSE2))
|
|
389
|
-
|
|
390
394
|
if (outmask & Cs._REDUCEDLENGTH_GEODESICSCALE):
|
|
391
395
|
dn1 = self._dn1
|
|
392
396
|
J12 = self._D0k2 * fsumf_(eF.deltaD(ssig2, csig2, dn2), -self._D1, sig12)
|
|
@@ -438,10 +442,9 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
438
442
|
S12 += gX.c2 * atan2(salp12, calp12)
|
|
439
443
|
r.set_(S12=S12)
|
|
440
444
|
|
|
441
|
-
r.set_(
|
|
445
|
+
r.set_(azi1=_norm180(self.azi1),
|
|
442
446
|
lat1=self.lat1, # == _fix90(lat1)
|
|
443
|
-
lon1=self.lon1 if (outmask & Cs.LONG_UNROLL) else self._lon1_norm180
|
|
444
|
-
azi1=_norm180(self.azi1))
|
|
447
|
+
lon1=self.lon1 if (outmask & Cs.LONG_UNROLL) else self._lon1_norm180)
|
|
445
448
|
return r
|
|
446
449
|
|
|
447
450
|
def _GenPosition(self, arcmode, s12_a12, outmask):
|
|
@@ -453,14 +456,24 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
453
456
|
r = self._GDictPosition(arcmode, s12_a12, outmask)
|
|
454
457
|
return r.toDirect9Tuple()
|
|
455
458
|
|
|
456
|
-
def _GenSet(self,
|
|
459
|
+
def _GenSet(self, debug, s12=None, a12=None, **llz2):
|
|
457
460
|
'''(INTERNAL) Aka C++ C{GenSetDistance}.
|
|
458
461
|
'''
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
462
|
+
Cs = Caps
|
|
463
|
+
if debug: # PYCHOK no cover
|
|
464
|
+
self._debug |= debug & Cs._DEBUG_ALL
|
|
465
|
+
# _CapsBase.debug._update(self)
|
|
466
|
+
if s12 is None:
|
|
467
|
+
if a12 is None: # see GeodesicExact.Line
|
|
468
|
+
return self
|
|
469
|
+
s12 = self._GDictPosition(True, a12, outmask=Cs.DISTANCE).s12 if a12 else _0_0
|
|
470
|
+
elif a12 is None:
|
|
471
|
+
a12 = self._GDictPosition(False, s12, 0).a12 if s12 else _0_0
|
|
472
|
+
self._s13 = s12
|
|
473
|
+
self._a13 = a12
|
|
474
|
+
self._caps |= Cs.DISTANCE | Cs.DISTANCE_IN
|
|
475
|
+
# _update_all(self) # new, from GeodesicExact.*Line
|
|
476
|
+
return _llz2line(self, **llz2)
|
|
464
477
|
|
|
465
478
|
@Property_RO
|
|
466
479
|
def geodesic(self):
|
|
@@ -498,7 +511,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
498
511
|
try:
|
|
499
512
|
return _MODS.geodesicw._Intersecant2(self, lat0, lon0, radius, tol=tol)
|
|
500
513
|
except (TypeError, ValueError) as x:
|
|
501
|
-
raise
|
|
514
|
+
raise _xError(x, lat0, lon0, radius, tol=_TOL)
|
|
502
515
|
|
|
503
516
|
@Property_RO
|
|
504
517
|
def _H0e2_f1(self):
|
|
@@ -594,8 +607,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
594
607
|
the reference point or C{NAN}.
|
|
595
608
|
'''
|
|
596
609
|
if self._a13 != a13:
|
|
597
|
-
self.
|
|
598
|
-
self._s13 = self._GDictPosition(True, a13, Caps.DISTANCE).s12 # if a13 else _0_0
|
|
610
|
+
self._GenSet(0, a12=a13)
|
|
599
611
|
_update_all(self)
|
|
600
612
|
return self._s13
|
|
601
613
|
|
|
@@ -608,10 +620,9 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
608
620
|
and the reference point or C{NAN}.
|
|
609
621
|
'''
|
|
610
622
|
if self._s13 != s13:
|
|
611
|
-
self.
|
|
612
|
-
self._a13 = self._GDictPosition(False, s13, 0).a12 if s13 else _0_0
|
|
623
|
+
self._GenSet(0, s12=s13)
|
|
613
624
|
_update_all(self)
|
|
614
|
-
return self._a13
|
|
625
|
+
return self._a13
|
|
615
626
|
|
|
616
627
|
@Property_RO
|
|
617
628
|
def _stau1_ctau1(self):
|
|
@@ -632,7 +643,7 @@ class _GeodesicLineExact(_GeodesicBase):
|
|
|
632
643
|
@return: C{GeodesicLineExact} (C{str}).
|
|
633
644
|
'''
|
|
634
645
|
C = _GeodesicLineExact
|
|
635
|
-
t = C.lat1, C.lon1, C.azi1, C.a13, C.s13, C.geodesic
|
|
646
|
+
t = C.lat1, C.lon1, C.azi1, C.a13, C.s13, C.caps, C.geodesic
|
|
636
647
|
return self._instr(props=t, **prec_sep_name)
|
|
637
648
|
|
|
638
649
|
|