pygeodesy 25.11.5__py2.py3-none-any.whl → 25.12.12__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. pygeodesy/__init__.py +25 -12
  2. pygeodesy/__main__.py +1 -1
  3. pygeodesy/albers.py +1 -1
  4. pygeodesy/angles.py +960 -0
  5. pygeodesy/auxilats/_CX_4.py +1 -1
  6. pygeodesy/auxilats/_CX_6.py +1 -1
  7. pygeodesy/auxilats/_CX_8.py +1 -1
  8. pygeodesy/auxilats/_CX_Rs.py +1 -1
  9. pygeodesy/auxilats/__init__.py +2 -2
  10. pygeodesy/auxilats/__main__.py +1 -1
  11. pygeodesy/auxilats/auxAngle.py +7 -8
  12. pygeodesy/auxilats/auxDLat.py +1 -1
  13. pygeodesy/auxilats/auxDST.py +1 -1
  14. pygeodesy/auxilats/auxLat.py +1 -1
  15. pygeodesy/auxilats/auxily.py +1 -1
  16. pygeodesy/azimuthal.py +6 -5
  17. pygeodesy/basics.py +14 -10
  18. pygeodesy/booleans.py +1 -1
  19. pygeodesy/cartesianBase.py +7 -7
  20. pygeodesy/clipy.py +1 -1
  21. pygeodesy/constants.py +27 -24
  22. pygeodesy/css.py +1 -1
  23. pygeodesy/datums.py +1 -1
  24. pygeodesy/deprecated/__init__.py +1 -1
  25. pygeodesy/deprecated/bases.py +1 -1
  26. pygeodesy/deprecated/classes.py +14 -7
  27. pygeodesy/deprecated/consterns.py +1 -1
  28. pygeodesy/deprecated/datum.py +1 -1
  29. pygeodesy/deprecated/functions.py +1 -1
  30. pygeodesy/deprecated/nvector.py +1 -1
  31. pygeodesy/deprecated/rhumbBase.py +1 -1
  32. pygeodesy/deprecated/rhumbaux.py +1 -1
  33. pygeodesy/deprecated/rhumbsolve.py +1 -1
  34. pygeodesy/deprecated/rhumbx.py +1 -1
  35. pygeodesy/dms.py +1 -1
  36. pygeodesy/ecef.py +1 -1
  37. pygeodesy/ecefLocals.py +1 -1
  38. pygeodesy/elevations.py +1 -1
  39. pygeodesy/ellipsoidalBase.py +1 -1
  40. pygeodesy/ellipsoidalBaseDI.py +1 -1
  41. pygeodesy/ellipsoidalExact.py +1 -1
  42. pygeodesy/ellipsoidalGeodSolve.py +1 -1
  43. pygeodesy/ellipsoidalKarney.py +1 -1
  44. pygeodesy/ellipsoidalNvector.py +1 -1
  45. pygeodesy/ellipsoidalVincenty.py +1 -1
  46. pygeodesy/ellipsoids.py +7 -6
  47. pygeodesy/elliptic.py +1 -1
  48. pygeodesy/epsg.py +1 -1
  49. pygeodesy/errors.py +8 -4
  50. pygeodesy/etm.py +1 -1
  51. pygeodesy/fmath.py +15 -8
  52. pygeodesy/formy.py +107 -5
  53. pygeodesy/frechet.py +1 -1
  54. pygeodesy/fstats.py +1 -1
  55. pygeodesy/fsums.py +1 -1
  56. pygeodesy/gars.py +1 -1
  57. pygeodesy/geod3solve.py +488 -0
  58. pygeodesy/geodesici.py +4 -4
  59. pygeodesy/geodesicw.py +1 -1
  60. pygeodesy/geodesicx/_C4_24.py +1 -1
  61. pygeodesy/geodesicx/_C4_27.py +1 -1
  62. pygeodesy/geodesicx/_C4_30.py +1 -1
  63. pygeodesy/geodesicx/__init__.py +1 -1
  64. pygeodesy/geodesicx/__main__.py +1 -1
  65. pygeodesy/geodesicx/gx.py +1 -1
  66. pygeodesy/geodesicx/gxarea.py +1 -1
  67. pygeodesy/geodesicx/gxbases.py +1 -1
  68. pygeodesy/geodesicx/gxline.py +1 -1
  69. pygeodesy/geodsolve.py +70 -102
  70. pygeodesy/geohash.py +1 -1
  71. pygeodesy/geoids.py +1 -1
  72. pygeodesy/hausdorff.py +1 -1
  73. pygeodesy/heights.py +1 -1
  74. pygeodesy/internals.py +1 -1
  75. pygeodesy/interns.py +3 -3
  76. pygeodesy/iters.py +1 -1
  77. pygeodesy/karney.py +132 -116
  78. pygeodesy/ktm.py +1 -1
  79. pygeodesy/latlonBase.py +1 -1
  80. pygeodesy/lazily.py +23 -12
  81. pygeodesy/lcc.py +1 -1
  82. pygeodesy/ltp.py +1 -1
  83. pygeodesy/ltpTuples.py +1 -1
  84. pygeodesy/mgrs.py +3 -3
  85. pygeodesy/named.py +14 -9
  86. pygeodesy/namedTuples.py +1 -1
  87. pygeodesy/nvectorBase.py +1 -1
  88. pygeodesy/osgr.py +1 -1
  89. pygeodesy/points.py +1 -1
  90. pygeodesy/props.py +1 -1
  91. pygeodesy/resections.py +1 -1
  92. pygeodesy/rhumb/__init__.py +8 -6
  93. pygeodesy/rhumb/aux_.py +1 -1
  94. pygeodesy/rhumb/bases.py +1 -1
  95. pygeodesy/rhumb/ekx.py +1 -1
  96. pygeodesy/rhumb/solve.py +91 -84
  97. pygeodesy/simplify.py +1 -1
  98. pygeodesy/solveBase.py +72 -49
  99. pygeodesy/sphericalBase.py +1 -1
  100. pygeodesy/sphericalNvector.py +1 -1
  101. pygeodesy/sphericalTrigonometry.py +1 -1
  102. pygeodesy/streprs.py +6 -4
  103. pygeodesy/trf.py +1 -1
  104. pygeodesy/triaxials/__init__.py +70 -0
  105. pygeodesy/triaxials/bases.py +935 -0
  106. pygeodesy/triaxials/conformal3.py +617 -0
  107. pygeodesy/triaxials/triaxial3.py +969 -0
  108. pygeodesy/{triaxials.py → triaxials/triaxial5.py} +353 -781
  109. pygeodesy/units.py +1 -1
  110. pygeodesy/unitsBase.py +1 -1
  111. pygeodesy/ups.py +2 -3
  112. pygeodesy/utily.py +17 -14
  113. pygeodesy/utm.py +1 -1
  114. pygeodesy/utmups.py +1 -1
  115. pygeodesy/utmupsBase.py +1 -1
  116. pygeodesy/vector2d.py +1 -1
  117. pygeodesy/vector3d.py +1 -1
  118. pygeodesy/vector3dBase.py +1 -1
  119. pygeodesy/webmercator.py +1 -1
  120. pygeodesy/wgrs.py +1 -1
  121. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.12.dist-info}/METADATA +12 -12
  122. pygeodesy-25.12.12.dist-info/RECORD +125 -0
  123. pygeodesy-25.11.5.dist-info/RECORD +0 -119
  124. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.12.dist-info}/WHEEL +0 -0
  125. {pygeodesy-25.11.5.dist-info → pygeodesy-25.12.12.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,488 @@
1
+
2
+ # -*- coding: utf-8 -*-
3
+
4
+ u'''Wrapper to invoke I{Karney}'s U{Geod3Solve
5
+ <https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>} utility
6
+ as a C{triaxial} geodesic, but intended I{mainly for testing purposes}.
7
+
8
+ Set env variable C{PYGEODESY_GEOD3SOLVE} to the (fully qualified) path
9
+ of the C{Geod3Solve} executable.
10
+ '''
11
+
12
+ from pygeodesy.angles import Ang, Deg, isAng, hypot
13
+ from pygeodesy.basics import _xinstanceof # typename
14
+ from pygeodesy.constants import _0_0, _0_5, _360_0
15
+ from pygeodesy.errors import GeodesicError, _xkwds_get
16
+ # from pygeodesy.fmath import hypot # from .angles
17
+ # from pygeodesy.geodesicx import GeodesicAreaExact # _MODS
18
+ from pygeodesy.interns import NN, _a12_, _DMAIN_, _s12_, _UNDER_, _UNUSED_
19
+ from pygeodesy.karney import Caps, _GTuple, _Xables, sincos2d
20
+ # from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY # from .solveBase
21
+ from pygeodesy.props import Property, Property_RO, property_RO
22
+ from pygeodesy.solveBase import _Solve3Base, _ALL_DOCS, _ALL_LAZY
23
+ from pygeodesy.triaxials.triaxial3 import Triaxial3, Triaxial3s
24
+ from pygeodesy.units import Degrees, Meter
25
+ # from pygeodesy.utily import sincos2d # from .karney
26
+
27
+ __all__ = _ALL_LAZY.geod3solve
28
+ __version__ = '25.12.12'
29
+
30
+ _Triaxial3_WGS84 = Triaxial3s.WGS84_3r # a=6378172, b=6378102, c=6356752
31
+
32
+
33
+ class Geodesic3Error(GeodesicError):
34
+ '''Error raised for issues in L{geod3solve<pygeodesy.geod3solve>}.
35
+ '''
36
+ pass
37
+
38
+
39
+ class Geod3Solve8Tuple(_GTuple):
40
+ '''8-Tuple C{(bet1, omg1, alp1, bet2, omg2, alp2, s12, a12)} with C{ellipsoidal}
41
+ latitudes C{bet1} and C{bet2}, C{ellipsoidal} longitudes C{omg1} and C{omg2},
42
+ forward azimuths C{alp1} and C{alp2} in bearings from North, distanc C{s12} in
43
+ C{meter}, conventionally and I{approximate} arc length {a12} in degrees, see
44
+ U{Geod3Solve<https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>}.
45
+ '''
46
+ # from Geod3Solve --help option -f ... bet1 omg1 alp1 bet2 omg2 alp2 s12
47
+ _Names_ = ('bet1', 'omg1', 'alp1', 'bet2', 'omg2', 'alp2', _s12_, _a12_)
48
+ _Units_ = ( Deg, Deg, Deg, Deg, Deg, Deg, Meter, Deg)
49
+
50
+
51
+ class _Geodesic3SolveBase(_Solve3Base):
52
+ '''(INTERNAL) Base class for L{Geodesic3Solve} and L{GeodesicLine3Solve}.
53
+ '''
54
+ _Error = Geodesic3Error
55
+ _Names_Direct = _Names_Distance = \
56
+ _Names_Inverse = Geod3Solve8Tuple._Names_[:7] # 7 only, always
57
+ _triaxial3 = _Triaxial3_WGS84
58
+ _Xable_name = _Xables.Geod3Solve.__name__ # typename
59
+ _Xable_path = _Xables.Geod3Solve()
60
+
61
+ @Property_RO
62
+ def a(self):
63
+ '''Get the triaxial's I{major} radius, semi-axis (C{meter}).
64
+ '''
65
+ return self._triaxial3.a
66
+
67
+ @Property_RO
68
+ def b(self):
69
+ '''Get the triaxial's I{middle} radius, semi-axis (C{meter}).
70
+ '''
71
+ return self._triaxial3.b
72
+
73
+ @Property_RO
74
+ def c(self):
75
+ '''Get the triaxial's I{minor} radius, semi-axis (C{meter}).
76
+ '''
77
+ return self._triaxial3.c
78
+
79
+ @Property_RO
80
+ def _cmdBasic(self):
81
+ '''(INTERNAL) Get the basic C{GeodSolve} cmd (C{tuple}).
82
+ '''
83
+ return (self.Geod3Solve, '-f') + (self._t_option +
84
+ self._p_option +
85
+ self._u_option)
86
+
87
+ @property_RO
88
+ def _e_option(self):
89
+ return ()
90
+
91
+ _mpd = _E_option = _e_option
92
+ flattening = f = ellipsoid = datum = None
93
+
94
+ @Property
95
+ def Geod3Solve(self):
96
+ '''Get the U{Geod3Solve<https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>}
97
+ executable (C{filename}).
98
+ '''
99
+ return self._Xable_path
100
+
101
+ @Geod3Solve.setter # PYCHOK setter!
102
+ def Geod3Solve(self, path):
103
+ '''Set the U{Geod3Solve<https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>}
104
+ executable (C{filename}), the (fully qualified) path to the C{Geod3Solve} executable.
105
+
106
+ @raise GeodesicError: Invalid B{C{path}}, B{C{path}} doesn't exist or
107
+ isn't the C{Geod3Solve} executable.
108
+ '''
109
+ self._setXable(path)
110
+
111
+ @property_RO
112
+ def _t_option(self):
113
+ return ('-t',) + self._toStdin(self._triaxial3._abc3)
114
+
115
+ def toStr(self, **prec_sep): # PYCHOK signature
116
+ '''Return this C{Geodesic3Solve} as string.
117
+
118
+ @kwarg prec_sep: See L{toStr<pygeodesy.solveBase._SolveBase.toStr>}.
119
+
120
+ @return: Geodesic3Solve items (C{str}).
121
+ '''
122
+ return _Solve3Base.toStr(self, Geod3Solve=self.Geod3Solve, **prec_sep)
123
+
124
+ @Property_RO
125
+ def _u_option(self):
126
+ return ('-u',) if self.unroll else ()
127
+
128
+
129
+ class Geodesic3Solve(_Geodesic3SolveBase):
130
+ '''Wrapper to invoke I{Karney}'s U{Geod3Solve<https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>}
131
+ as a C{triaxial} version of I{Karney}'s Python class U{Geodesic<https://GeographicLib.SourceForge.io/C++/doc/
132
+ python/code.html#geographiclib.geodesic.Geodesic>}.
133
+
134
+ @note: Use property C{GeodSolve} or env variable C{PYGEODESY_GEOD3SOLVE} to specify the (fully
135
+ qualified) path to the C{Geod3Solve} executable.
136
+
137
+ @note: This C{geodesic} is intended I{for testing purposes only}, it invokes the C{GeodSolve}
138
+ executable for I{every} method call.
139
+ '''
140
+
141
+ def __init__(self, triaxial3=_Triaxial3_WGS84, path=NN, **name):
142
+ '''New C{Solve} instance.
143
+
144
+ @arg triaxial3: A triaxial (L{Triaxial3}), default C{Triaxial3s.WGS84_3r}.
145
+ @kwarg path: Optionally, the (fully qualified) path to the C{GeodSolve}
146
+ or C{RhumbSolve} executable (C{filename}).
147
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
148
+
149
+ @raise TypeError: Invalid B{C{a_ellipsoid}} or B{C{f}}.
150
+ '''
151
+ _xinstanceof(Triaxial3, triaxial3=triaxial3)
152
+ if self._triaxial3 != triaxial3:
153
+ self._triaxial3 = triaxial3
154
+ if name:
155
+ self.name = name
156
+ if path:
157
+ self._setXable(path)
158
+
159
+ def _a12d(self, r):
160
+ '''(INTERNAL) Add arc C{a12} in degrees to C{GDict}.
161
+ '''
162
+ a = r.s12 or _0_0
163
+ if a:
164
+ z = _toAzi(r.alp1) + _toAzi(r.alp2)
165
+ s, c = sincos2d(z * _0_5)
166
+ t = self.triaxial3
167
+ a *= hypot(s / t._ab_elliperim, # azimuth!
168
+ c / t._bc_elliperim) * _360_0
169
+ r[_a12_] = a
170
+ return r
171
+
172
+ def Direct(self, bet1, omg1, alp1, s12, outmask=_UNUSED_, **unit): # PYCHOK unused
173
+ '''Return the C{Direct} result at distance C{s12}.
174
+ '''
175
+ bet1, omg1, alp1 = _toDegrees(bet1, omg1, alp1, **unit)
176
+ r = self._GDictDirect(bet1, omg1, alp1, False, s12)
177
+ return self._a12d(r)
178
+
179
+ def DirectLine(self, bet1, omg1, alp1, caps=Caps.ALL, **unit_name):
180
+ '''Set up a L{GeodesicLine3Solve} to compute several points
181
+ on a single geodesic.
182
+
183
+ @arg bet1: Ellipsoidal Latitude of the first point (C{Ang} or B{C{unit}}).
184
+ @arg omg1: Ellipsoidal Longitude of the first point (C{Ang} or B{C{unit}}).
185
+ @arg alp1: Azimuth at the first point (compass C{degrees}, C{Ang} or C{unit}).
186
+ @kwarg caps: Desired capabilities for the L{GeodesicLine3Solve} instance.
187
+ @kwarg unit_name: Optional C{B{name}=NN} (C{str}) and scalar C{B{unit}=}L{Degrees}
188
+ (or L{Degrees}).
189
+
190
+ @return: A L{GeodesicLine3Solve} instance.
191
+
192
+ @see: C++ U{GeodesicExact.Line
193
+ <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>}
194
+ and Python U{Geodesic.Line<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
195
+ '''
196
+ return GeodesicLine3Solve(self, bet1, omg1, alp1, caps=caps, **unit_name)
197
+
198
+ Line = DirectLine # ArcDirectLine
199
+
200
+ def Inverse(self, bet1, omg1, bet2, omg2, outmask=_UNUSED_, **unit): # PYCHOK unused
201
+ '''Return the C{Inverse} result.
202
+ '''
203
+ r = self._GDictInverse(*_toDegrees(bet1, omg1, bet2, omg2, **unit))
204
+ return self._a12d(r)
205
+
206
+ def InverseLine(self, bet1, omg1, bet2, omg2, caps=Caps.ALL, **unit_name):
207
+ '''Set up a L{GeodesicLine3Solve} to compute several points
208
+ on a single geodesic.
209
+
210
+ @arg bet1: Latitude of the first point (C{Ang} or B{C{unit}}).
211
+ @arg omg1: Longitude of the first point (C{Ang} or B{C{unit}}).
212
+ @arg bet2: Latitude of the second point (C{Ang} or B{C{unit}}).
213
+ @arg omg2: Longitude of the second point (C{Ang} or B{C{unit}}).
214
+ @kwarg caps: Desired capabilities for the L{GeodesicLine3Solve} instance.
215
+ @kwarg unit_name: Optional C{B{name}=NN} (C{str}) and scalar C{B{unit}=}L{Degrees}
216
+ (or L{Degrees}).
217
+
218
+ @return: A L{GeodesicLine3Solve} instance.
219
+
220
+ @note: Both B{C{bet1}} and B{C{bet2}} should in the range C{[-90, +90]}.
221
+
222
+ @see: C++ U{GeodesicExact.InverseLine
223
+ <https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GeodesicExact.html>} and
224
+ Python U{Geodesic.InverseLine<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
225
+ '''
226
+ r = self.Inverse(bet1, omg1, bet2, omg2, **unit_name)
227
+ gl = GeodesicLine3Solve(self, r.bet1, r.omg1, r.alp1, caps=caps, **unit_name)
228
+ # gl._a13 = r.a12 # gl.SetArc(r.a12)
229
+ # gl._s13 = r.s12 # gl.SetDistance(r.s12)
230
+ return gl
231
+
232
+ def toStr(self, **prec_sep_other): # PYCHOK signature
233
+ '''Return this C{Geodesic3Solve} as string.
234
+
235
+ @kwarg prec_sep: See L{toStr<pygeodesy.solveBase._Solve3Base.toStr>}.
236
+
237
+ @return: Geodesic3Solve items (C{str}).
238
+ '''
239
+ return _Solve3Base.toStr(self, Geod3Solve=self.Geod3Solve, **prec_sep_other)
240
+
241
+ @property_RO
242
+ def triaxial3(self):
243
+ '''Get the triaxial (C{Triaxial3}).
244
+ '''
245
+ return self._triaxial3
246
+
247
+
248
+ class GeodesicLine3Solve(_Geodesic3SolveBase): # _SolveGDictLineBase):
249
+ '''Wrapper to invoke I{Karney}'s U{Geod3Solve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.3.html>}
250
+ as a C{triaxial} version of I{Karney}'s Python class U{GeodesicLine<https://GeographicLib.SourceForge.io/
251
+ C++/doc/python/code.html#geographiclib.geodesicline.GeodesicLine>}.
252
+
253
+ @note: Use property C{GeodSolve} or env variable C{PYGEODESY_GEODSOLVE} to specify the (fully
254
+ qualified) path to the C{GeodSolve} executable.
255
+
256
+ @note: This C{geodesic} is intended I{for testing purposes only}, it invokes the C{GeodSolve}
257
+ executable for I{every} method call.
258
+ '''
259
+ # _a13 = \
260
+ # _s13 = NAN # see GeodesicSolve._InverseLine
261
+ _solve = None # L{Geodesic3Solve} instance
262
+
263
+ def __init__(self, geodesic3, bet1, omg1, alp1, caps=Caps.ALL, **unit_name):
264
+ '''New L{GeodesicLine3Solve} instance, allowing points to be found along
265
+ a geodesic starting at C{(B{bet1}, B{omg1})} with azimuth B{C{alp1}}.
266
+
267
+ @arg geodesic3: The geodesic to use (L{Geodesic3Solve}).
268
+ @arg bet1: Ellipsoidal latitude of the first point (C{Ang} or B{C{unit}}).
269
+ @arg omg1: Ellipsoidal longitude of the first point (C{Ang} or B{C{unit}}).
270
+ @arg alp1: Azimuth at the first point (compass C{degrees}, C{Ang} or C{unit}).
271
+ @kwarg caps: Bit-or'ed combination of L{Caps<pygeodesy.karney.Caps>} values
272
+ specifying the capabilities the L{GeodesicLine3Solve} instance
273
+ should possess, C{B{caps}=Caps.ALL} always. Include C{Caps.LINE_OFF}
274
+ if updates to the B{C{geodesic3}} should I{not be reflected} in this
275
+ L{GeodesicLine3Solve} instance.
276
+ @kwarg unit_name: Optional C{B{name}=NN} (C{str}) and scalar C{B{unit}=}L{Degrees}
277
+ (or L{Degrees}).
278
+
279
+ @raise Geodesic3Error: Invalid path for the C{Geod3Solve} executable or isn't the
280
+ C{Geod3Solve} executable, see property C{geodesic3.Geod3Solve}.
281
+
282
+ @raise TypeError: Invalid B{C{geodesic3}}.
283
+ '''
284
+ _xinstanceof(Geodesic3Solve, geodesic3=geodesic3)
285
+ if (caps & Caps.LINE_OFF): # copy to avoid updates
286
+ geodesic3 = geodesic3.copy(deep=False, name=_UNDER_(NN, geodesic3.name)) # NOT _under!
287
+ self._bet1, \
288
+ self._omg1, \
289
+ self._alp1 = _toDegrees(bet1, omg1, alp1, **unit_name)
290
+ self._caps = caps | Caps._AZIMUTH_LATITUDE_LONG_UNROLL
291
+ self._debug = geodesic3._debug & Caps._DEBUG_ALL
292
+ self._solve = geodesic3
293
+ try:
294
+ self.Geod3Solve = geodesic3.Geod3Solve # geodesic or copy of geodesic
295
+ except GeodesicError:
296
+ pass
297
+ if unit_name:
298
+ name = _xkwds_get(unit_name, name=None)
299
+ if name:
300
+ self.name = name
301
+
302
+ @Property_RO
303
+ def alp1(self):
304
+ '''Get the azimuth at the first point (compass C{degrees}).
305
+ '''
306
+ return self._alp1
307
+
308
+ # azi12 = alp1 # like RhumbLineSolve
309
+
310
+ # @Property_RO
311
+ # def azi1_sincos2(self):
312
+ # '''Get the sine and cosine of the first point's azimuth (2-tuple C{(sin, cos)}).
313
+ # '''
314
+ # return _sincos2d(self.alp1)
315
+ #
316
+ # azi12_sincos2 = azi1_sincos2
317
+
318
+ @Property_RO
319
+ def bet1(self):
320
+ '''Get the I{ellipsoidal} latitude of the first point (C{degrees}).
321
+ '''
322
+ return self._bet1
323
+
324
+ @Property_RO
325
+ def _cmdDistance(self):
326
+ '''(INTERNAL) Get the C{Geod3Solve} I{-L} cmd (C{tuple}).
327
+ '''
328
+ t = self.bet1, self.omg1, self.alp1
329
+ return self._cmdBasic + ('-L',) + self._toStdin(t)
330
+
331
+ @property_RO
332
+ def geodesic3(self):
333
+ '''Get the C{triaxial} geodesic (L{Geodesic3Solve}).
334
+ '''
335
+ return self._solve # see .solveBase._SolveLineBase
336
+
337
+ def Intersecant2(self, bet0, omg0, radius, **kwds): # PYCHOK no cover
338
+ '''B{Not implemented}, throws a C{NotImplementedError} always.'''
339
+ self._notImplemented(bet0, omg0, radius, **kwds)
340
+
341
+ @Property_RO
342
+ def omg1(self):
343
+ '''Get the I{ellipsoidal} longitude of the first point (C{degrees}).
344
+ '''
345
+ return self._omg1
346
+
347
+ def PlumbTo(self, bet0, omg0, **kwds): # PYCHOK no cover
348
+ '''B{Not implemented}, throws a C{NotImplementedError} always.'''
349
+ self._notImplemented(bet0, omg0, **kwds)
350
+
351
+ def Position(self, s12, outmask=Caps.ALL): # PYCHOK usused
352
+ '''Find the position on the line given B{C{s12}}.
353
+
354
+ @arg s12: Distance from the first point to the second (C{meter}).
355
+
356
+ @return: A C{GDict} with 7 items C{bet1, omg1, alp1, bet2, omg2, alp2, s12}.
357
+ '''
358
+ r = self._GDictInvoke(self._cmdDistance, self._Names_Distance, s12) # ._unCaps(outmask)
359
+ return self.geodesic3._a12d(r)
360
+
361
+ def toStr(self, **prec_sep_other): # PYCHOK signature
362
+ '''Return this C{GeodesicLine3Solve} as string.
363
+
364
+ @kwarg prec_sep: See L{toStr<pygeodesy.solveBase._Solve3Base.toStr>}.
365
+
366
+ @return: GeodesicLine3Solve items (C{str}).
367
+ '''
368
+ return _Solve3Base.toStr(self, bet1=self.bet1, omg1=self.omg1, alp1=self.alp1,
369
+ geodesic3=self.geodesic3, **prec_sep_other)
370
+
371
+ @property_RO
372
+ def triaxial3(self):
373
+ '''Get the triaxial (C{Triaxial3}).
374
+ '''
375
+ return self.geodesic3.triaxial3
376
+
377
+
378
+ def _toAzi(alp): # as degrees
379
+ return alp.degrees0 if isAng(alp) else alp
380
+
381
+
382
+ def _toDegrees(*angs, **unit_name):
383
+ unit = _xkwds_get(unit_name, unit=Degrees)
384
+ for ang in angs:
385
+ if not isAng(ang):
386
+ ang = Ang.fromScalar(ang, unit=unit)
387
+ yield ang.degrees
388
+
389
+
390
+ __all__ += _ALL_DOCS(_Geodesic3SolveBase)
391
+
392
+ if __name__ == _DMAIN_:
393
+
394
+ def _main():
395
+ from pygeodesy import printf
396
+ from sys import argv
397
+
398
+ gS = Geodesic3Solve(name='Test')
399
+ gS.verbose = v = '--verbose' in argv # or '-v' in argv
400
+
401
+ if not _Xables.X_OK(gS.Geod3Solve): # not set
402
+ gS.Geod3Solve = _Xables.Geod3Solve(_Xables.bin_)
403
+ printf('version: %s', gS.version, nt=v)
404
+
405
+ r = gS.Direct(40.6, -73.8, 51, 5.5e6)
406
+ printf('Direct: %r', r, nt=v)
407
+
408
+ printf('Inverse: %r', gS.Inverse( 40.6, -73.8, 51.6, -0.5), nt=v)
409
+
410
+ glS = GeodesicLine3Solve(gS, 40.6, -73.8, 51, name='LineTest')
411
+ printf('Line: %r', glS)
412
+ p = glS.Position(5.5e6)
413
+ printf('Position: %r %s', p, p == r)
414
+
415
+ _main()
416
+
417
+ # % python3 -m pygeodesy.geod3solve
418
+
419
+ # version: /opt/local/bin/Geod3Solve: GeographicLib version 2.7
420
+ # Direct: GDict(a12=49.410276, alp1=51.0, alp2=107.340251, bet1=40.6, bet2=51.895816, omg1=-73.8, omg2=-1.038308, s12=5500000.0)
421
+ # Inverse: GDict(a12=49.816802, alp1=51.235527, alp2=107.918138, bet1=40.6, bet2=51.6, omg1=-73.8, omg2=-0.5, s12=5545275.651379)
422
+ # Line: GeodesicLine3Solve(alp1=51.0, bet1=40.6, geodesic3=Geodesic3Solve(Geod3Solve='/opt/local/bin/Geod3Solve', invokation=3, status=0), invokation=1, omg1=-73.8, status=0)
423
+ # Position: GDict(a12=49.410276, alp1=51.0, alp2=107.340251, bet1=40.6, bet2=51.895816, omg1=-73.8, omg2=-1.038308, s12=5500000.0) True
424
+
425
+
426
+ # % python3 -m pygeodesy.geod3solve --verbose
427
+
428
+ # Geodesic3Solve 'Test'@1: /opt/local/bin/Geod3Solve --version (invoke)
429
+ # Geodesic3Solve 'Test'@1: '/opt/local/bin/Geod3Solve: GeographicLib version 2.7' (0, stdout/-err)
430
+ # Geodesic3Solve 'Test'@1: /opt/local/bin/Geod3Solve: GeographicLib version 2.7 (0)
431
+ # version: /opt/local/bin/Geod3Solve: GeographicLib version 2.7
432
+ #
433
+ # Geodesic3Solve 'Test'@2: /opt/local/bin/Geod3Solve -f -t 6378172.0 6378102.0 6356752.0 -p 10 \ 40.6 -73.8 51.0 5500000.0 (Direct)
434
+ # Geodesic3Solve 'Test'@2: '40.600000000000001 -73.799999999999997 51.000000000000007 51.895816223972680 -1.038308043217667 107.340251322641734 5500000.0000000000' (0, stdout/-err)
435
+ # Geodesic3Solve 'Test'@2: bet1=40.600000000000001, omg1=-73.799999999999997, alp1=51.000000000000007, bet2=51.89581622397268, omg2=-1.038308043217667, alp2=107.340251322641734, s12=5500000.0 (0)
436
+ # Direct: GDict(a12=49.410276, alp1=51.0, alp2=107.340251, bet1=40.6, bet2=51.895816, omg1=-73.8, omg2=-1.038308, s12=5500000.0)
437
+ #
438
+ # Geodesic3Solve 'Test'@3: /opt/local/bin/Geod3Solve -f -t 6378172.0 6378102.0 6356752.0 -p 10 -i \ 40.6 -73.8 51.6 -0.5 (Inverse)
439
+ # Geodesic3Solve 'Test'@3: '40.600000000000001 -73.799999999999997 51.235527494379824 51.600000000000001 -0.500000000000000 107.918137616344865 5545275.6513788253' (0, stdout/-err)
440
+ # Geodesic3Solve 'Test'@3: bet1=40.600000000000001, omg1=-73.799999999999997, alp1=51.235527494379824, bet2=51.600000000000001, omg2=-0.5, alp2=107.918137616344865, s12=5545275.6513788253 (0)
441
+ # Inverse: GDict(a12=49.816802, alp1=51.235527, alp2=107.918138, bet1=40.6, bet2=51.6, omg1=-73.8, omg2=-0.5, s12=5545275.651379)
442
+ #
443
+ # Line: GeodesicLine3Solve(alp1=51.0, bet1=40.6, geodesic3=Geodesic3Solve(Geod3Solve='/opt/local/bin/Geod3Solve', invokation=3, status=0), invokation=1, omg1=-73.8, status=0)
444
+ # Position: GDict(a12=49.410276, alp1=51.0, alp2=107.340251, bet1=40.6, bet2=51.895816, omg1=-73.8, omg2=-1.038308, s12=5500000.0) True
445
+
446
+
447
+ # Examples <https://GeographicLib.SourceForge.io/C++/doc/Geod3Solve.1.html>
448
+
449
+ # % echo 40:38:23N 073:46:44W-19.43W X 01:21:33N 103:59:22E-19.43W | tr X '\n' | Cart3Convert -G | Cart3Convert -E -r | tr '\n' ' ' | Geod3Solve -i -p 0 -f
450
+ # 40.57193 -54.38111 3.20824 1.35529 123.41971 177.48319 15347602
451
+ # % echo 40:38:23N 073:46:44W-19.43W X 01:21:33N 103:59:22E-19.43W | tr X '\n' | Cart3Convert -G | Cart3Convert -E -r | tr '\n' ' ' | Geod3Solve -i -p 0
452
+ # 3.20824 177.48319 15347602
453
+ # % echo 40:38:23N 073:46:44W-19.43W X 01:21:33N 103:59:22E-19.43W | tr X '\n' | Cart3Convert -G | Cart3Convert -E -r | tr '\n' ' ' | Geod3Solve -i -p 9
454
+ # 3.20824419242752 177.48319457984906 15347602.214888915
455
+
456
+ # % Geod3Solve -L 40.57193 -54.38111 3.20824
457
+ # 15347602
458
+ # 1.35529159 123.41971119 177.48319768
459
+ # 15347602
460
+ # 1.35529159 123.41971119 177.48319768
461
+ # % Geod3Solve -L 40.57193 -54.38111 3.20824 -f
462
+ # 15347602
463
+ # 40.57193000 -54.38111000 3.20824000 1.35529159 123.41971119 177.48319768 15347602.000
464
+ # % Geod3Solve -L 40.57193 -54.38111 3.20824 -f -p 9
465
+ # 15347602
466
+ # 40.57193000000000 -54.38111000000000 3.20824000000000 1.35529159010289 123.41971119123770 177.48319768195134 15347602.000000000
467
+
468
+ # **) MIT License
469
+ #
470
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
471
+ #
472
+ # Permission is hereby granted, free of charge, to any person obtaining a
473
+ # copy of this software and associated documentation files (the "Software"),
474
+ # to deal in the Software without restriction, including without limitation
475
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
476
+ # and/or sell copies of the Software, and to permit persons to whom the
477
+ # Software is furnished to do so, subject to the following conditions:
478
+ #
479
+ # The above copyright notice and this permission notice shall be included
480
+ # in all copies or substantial portions of the Software.
481
+ #
482
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
483
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
484
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
485
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
486
+ # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
487
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
488
+ # OTHER DEALINGS IN THE SOFTWARE.
pygeodesy/geodesici.py CHANGED
@@ -487,7 +487,7 @@ class Intersectool(_IntersectBase, _SolveCapsBase):
487
487
  @raise GeodesicError: The eccentricity of the B{C{geodesic}}'s ellipsoid is too
488
488
  large or no initial convergence.
489
489
 
490
- @see: The B{Note} at I{Karney}'s C++ U{Intersect<https://GeographicLib.sourceforge.io/
490
+ @see: The B{Note} at I{Karney}'s C++ U{Intersect<https://GeographicLib.SourceForge.io/
491
491
  C++/doc/classGeographicLib_1_1Intersect.html#ae41f54c9a44836f6c8f140f6994930cf>}.
492
492
  '''
493
493
  g = self._GeodesicExact() if a_geodesic is None else (a_geodesic if f is None else
@@ -777,7 +777,7 @@ class Intersector(_IntersectBase):
777
777
  wrapped L{GeodesicLine<pygeodesy.geodesicw.GeodesicLine>} or
778
778
  L{GeodesicLineSolve<pygeodesy.geodsolve.GeodesicLineSolve>}.
779
779
 
780
- @see: I{Karney}'s C++ class U{Intersect<https://GeographicLib.sourceforge.io/
780
+ @see: I{Karney}'s C++ class U{Intersect<https://GeographicLib.SourceForge.io/
781
781
  C++/doc/classGeographicLib_1_1Intersect.html#details>} for more details.
782
782
  '''
783
783
 
@@ -792,7 +792,7 @@ class Intersector(_IntersectBase):
792
792
  @raise GeodesicError: The eccentricity of the B{C{geodesic}}'s ellipsoid is too
793
793
  large or no initial convergence.
794
794
 
795
- @see: The B{Note} at I{Karney}'s C++ U{Intersect<https://GeographicLib.sourceforge.io/
795
+ @see: The B{Note} at I{Karney}'s C++ U{Intersect<https://GeographicLib.SourceForge.io/
796
796
  C++/doc/classGeographicLib_1_1Intersect.html#ae41f54c9a44836f6c8f140f6994930cf>}.
797
797
  '''
798
798
  _IntersectBase.__init__(self, geodesic, **name)
@@ -1775,7 +1775,7 @@ if __name__ == _DMAIN_: # MCCABE 14
1775
1775
 
1776
1776
  # **) MIT License
1777
1777
  #
1778
- # Copyright (C) 2024-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1778
+ # Copyright (C) 2024-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1779
1779
  #
1780
1780
  # Permission is hereby granted, free of charge, to any person obtaining a
1781
1781
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/geodesicw.py CHANGED
@@ -609,7 +609,7 @@ def _PlumbTo(gl, lat0, lon0, est=None, tol=_TOL):
609
609
 
610
610
  # **) MIT License
611
611
  #
612
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
612
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
613
613
  #
614
614
  # Permission is hereby granted, free of charge, to any person obtaining a
615
615
  # copy of this software and associated documentation files (the "Software"),
@@ -1676,7 +1676,7 @@ del _g, _Gfloats, _f, _f2
1676
1676
 
1677
1677
  # **) MIT License
1678
1678
  #
1679
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1679
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1680
1680
  #
1681
1681
  # Permission is hereby granted, free of charge, to any person obtaining a
1682
1682
  # copy of this software and associated documentation files (the "Software"),
@@ -2372,7 +2372,7 @@ del _g, _Gfloats, _f, _f2
2372
2372
 
2373
2373
  # **) MIT License
2374
2374
  #
2375
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
2375
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
2376
2376
  #
2377
2377
  # Permission is hereby granted, free of charge, to any person obtaining a
2378
2378
  # copy of this software and associated documentation files (the "Software"),
@@ -3278,7 +3278,7 @@ del _g, _Gfloats, _f, _f2
3278
3278
 
3279
3279
  # **) MIT License
3280
3280
  #
3281
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
3281
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
3282
3282
  #
3283
3283
  # Permission is hereby granted, free of charge, to any person obtaining a
3284
3284
  # copy of this software and associated documentation files (the "Software"),
@@ -27,7 +27,7 @@ __version__ = '25.09.02'
27
27
 
28
28
  # **) MIT License
29
29
  #
30
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
30
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
31
31
  #
32
32
  # Permission is hereby granted, free of charge, to any person obtaining a
33
33
  # copy of this software and associated documentation files (the "Software"),
@@ -67,7 +67,7 @@ _main(C4order=int(argv[1])) if len(argv) == 2 and argv[1].isdigit() else _main()
67
67
 
68
68
  # **) MIT License
69
69
  #
70
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
70
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
71
71
  #
72
72
  # Permission is hereby granted, free of charge, to any person obtaining a
73
73
  # copy of this software and associated documentation files (the "Software"),
pygeodesy/geodesicx/gx.py CHANGED
@@ -1343,7 +1343,7 @@ __all__ += _ALL_DOCS(GeodesicExact, GeodesicLineExact)
1343
1343
 
1344
1344
  # **) MIT License
1345
1345
  #
1346
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
1346
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
1347
1347
  #
1348
1348
  # Permission is hereby granted, free of charge, to any person obtaining a
1349
1349
  # copy of this software and associated documentation files (the "Software"),
@@ -506,7 +506,7 @@ __all__ += _ALL_DOCS(GeodesicAreaExact, PolygonArea)
506
506
 
507
507
  # **) MIT License
508
508
  #
509
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
509
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
510
510
  #
511
511
  # Permission is hereby granted, free of charge, to any person obtaining a
512
512
  # copy of this software and associated documentation files (the "Software"),
@@ -165,7 +165,7 @@ def _xnC4(**name_nC4):
165
165
 
166
166
  # **) MIT License
167
167
  #
168
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
168
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
169
169
  #
170
170
  # Permission is hereby granted, free of charge, to any person obtaining a
171
171
  # copy of this software and associated documentation files (the "Software"),
@@ -667,7 +667,7 @@ __all__ += _ALL_DOCS(_GeodesicLineExact)
667
667
 
668
668
  # **) MIT License
669
669
  #
670
- # Copyright (C) 2016-2025 -- mrJean1 at Gmail -- All Rights Reserved.
670
+ # Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.
671
671
  #
672
672
  # Permission is hereby granted, free of charge, to any person obtaining a
673
673
  # copy of this software and associated documentation files (the "Software"),