pygeodesy 24.3.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.3.24.dist-info/METADATA +272 -0
- PyGeodesy-24.3.24.dist-info/RECORD +115 -0
- PyGeodesy-24.3.24.dist-info/WHEEL +6 -0
- PyGeodesy-24.3.24.dist-info/top_level.txt +1 -0
- pygeodesy/LICENSE +21 -0
- pygeodesy/__init__.py +615 -0
- pygeodesy/__main__.py +103 -0
- pygeodesy/albers.py +867 -0
- pygeodesy/auxilats/_CX_4.py +218 -0
- pygeodesy/auxilats/_CX_6.py +314 -0
- pygeodesy/auxilats/_CX_8.py +475 -0
- pygeodesy/auxilats/__init__.py +54 -0
- pygeodesy/auxilats/__main__.py +86 -0
- pygeodesy/auxilats/auxAngle.py +548 -0
- pygeodesy/auxilats/auxDLat.py +302 -0
- pygeodesy/auxilats/auxDST.py +296 -0
- pygeodesy/auxilats/auxLat.py +848 -0
- pygeodesy/auxilats/auxily.py +272 -0
- pygeodesy/azimuthal.py +1150 -0
- pygeodesy/basics.py +892 -0
- pygeodesy/booleans.py +2031 -0
- pygeodesy/cartesianBase.py +1062 -0
- pygeodesy/clipy.py +704 -0
- pygeodesy/constants.py +516 -0
- pygeodesy/css.py +660 -0
- pygeodesy/datums.py +752 -0
- pygeodesy/deprecated/__init__.py +61 -0
- pygeodesy/deprecated/bases.py +40 -0
- pygeodesy/deprecated/classes.py +262 -0
- pygeodesy/deprecated/consterns.py +54 -0
- pygeodesy/deprecated/datum.py +40 -0
- pygeodesy/deprecated/functions.py +375 -0
- pygeodesy/deprecated/nvector.py +48 -0
- pygeodesy/deprecated/rhumbBase.py +32 -0
- pygeodesy/deprecated/rhumbaux.py +33 -0
- pygeodesy/deprecated/rhumbsolve.py +33 -0
- pygeodesy/deprecated/rhumbx.py +33 -0
- pygeodesy/dms.py +986 -0
- pygeodesy/ecef.py +1348 -0
- pygeodesy/elevations.py +279 -0
- pygeodesy/ellipsoidalBase.py +1224 -0
- pygeodesy/ellipsoidalBaseDI.py +913 -0
- pygeodesy/ellipsoidalExact.py +343 -0
- pygeodesy/ellipsoidalGeodSolve.py +343 -0
- pygeodesy/ellipsoidalKarney.py +403 -0
- pygeodesy/ellipsoidalNvector.py +685 -0
- pygeodesy/ellipsoidalVincenty.py +590 -0
- pygeodesy/ellipsoids.py +2476 -0
- pygeodesy/elliptic.py +1198 -0
- pygeodesy/epsg.py +243 -0
- pygeodesy/errors.py +804 -0
- pygeodesy/etm.py +1190 -0
- pygeodesy/fmath.py +1013 -0
- pygeodesy/formy.py +1818 -0
- pygeodesy/frechet.py +865 -0
- pygeodesy/fstats.py +760 -0
- pygeodesy/fsums.py +1898 -0
- pygeodesy/gars.py +358 -0
- pygeodesy/geodesicw.py +581 -0
- pygeodesy/geodesicx/_C4_24.py +1699 -0
- pygeodesy/geodesicx/_C4_27.py +2395 -0
- pygeodesy/geodesicx/_C4_30.py +3301 -0
- pygeodesy/geodesicx/__init__.py +48 -0
- pygeodesy/geodesicx/__main__.py +91 -0
- pygeodesy/geodesicx/gx.py +1382 -0
- pygeodesy/geodesicx/gxarea.py +535 -0
- pygeodesy/geodesicx/gxbases.py +154 -0
- pygeodesy/geodesicx/gxline.py +669 -0
- pygeodesy/geodsolve.py +426 -0
- pygeodesy/geohash.py +914 -0
- pygeodesy/geoids.py +1884 -0
- pygeodesy/hausdorff.py +892 -0
- pygeodesy/heights.py +1155 -0
- pygeodesy/interns.py +687 -0
- pygeodesy/iters.py +545 -0
- pygeodesy/karney.py +919 -0
- pygeodesy/ktm.py +633 -0
- pygeodesy/latlonBase.py +1766 -0
- pygeodesy/lazily.py +960 -0
- pygeodesy/lcc.py +684 -0
- pygeodesy/ltp.py +1107 -0
- pygeodesy/ltpTuples.py +1563 -0
- pygeodesy/mgrs.py +721 -0
- pygeodesy/named.py +1324 -0
- pygeodesy/namedTuples.py +683 -0
- pygeodesy/nvectorBase.py +695 -0
- pygeodesy/osgr.py +781 -0
- pygeodesy/points.py +1686 -0
- pygeodesy/props.py +628 -0
- pygeodesy/resections.py +1048 -0
- pygeodesy/rhumb/__init__.py +46 -0
- pygeodesy/rhumb/aux_.py +397 -0
- pygeodesy/rhumb/bases.py +1148 -0
- pygeodesy/rhumb/ekx.py +563 -0
- pygeodesy/rhumb/solve.py +572 -0
- pygeodesy/simplify.py +647 -0
- pygeodesy/solveBase.py +472 -0
- pygeodesy/sphericalBase.py +724 -0
- pygeodesy/sphericalNvector.py +1264 -0
- pygeodesy/sphericalTrigonometry.py +1447 -0
- pygeodesy/streprs.py +627 -0
- pygeodesy/trf.py +2079 -0
- pygeodesy/triaxials.py +1484 -0
- pygeodesy/units.py +969 -0
- pygeodesy/unitsBase.py +349 -0
- pygeodesy/ups.py +538 -0
- pygeodesy/utily.py +1231 -0
- pygeodesy/utm.py +762 -0
- pygeodesy/utmups.py +318 -0
- pygeodesy/utmupsBase.py +517 -0
- pygeodesy/vector2d.py +785 -0
- pygeodesy/vector3d.py +968 -0
- pygeodesy/vector3dBase.py +1049 -0
- pygeodesy/webmercator.py +383 -0
- pygeodesy/wgrs.py +439 -0
pygeodesy/solveBase.py
ADDED
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''(INTERNAL) Private base classes for L{pygeodesy.geodsolve} and L{pygeodesy.rhumb.solve}.
|
|
5
|
+
'''
|
|
6
|
+
|
|
7
|
+
from pygeodesy.basics import map2, ub2str, _zip
|
|
8
|
+
from pygeodesy.constants import DIG
|
|
9
|
+
from pygeodesy.datums import _earth_datum, _WGS84, _EWGS84
|
|
10
|
+
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
11
|
+
from pygeodesy.errors import _AssertionError, _xkwds_get, _xkwds_item2
|
|
12
|
+
from pygeodesy.interns import NN, _0_, _BACKSLASH_, _COMMASPACE_, _enquote, \
|
|
13
|
+
_EQUAL_, _Error_, _not_, _SPACE_, _UNUSED_
|
|
14
|
+
from pygeodesy.karney import Caps, _CapsBase, GDict
|
|
15
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, printf, _unlazy
|
|
16
|
+
from pygeodesy.named import callername, notOverloaded
|
|
17
|
+
from pygeodesy.props import Property, Property_RO, property_RO, _update_all
|
|
18
|
+
from pygeodesy.streprs import Fmt, fstr, fstrzs, pairs, strs
|
|
19
|
+
from pygeodesy.units import Precision_
|
|
20
|
+
from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
|
|
21
|
+
|
|
22
|
+
from subprocess import PIPE as _PIPE, Popen as _Popen, STDOUT as _STDOUT
|
|
23
|
+
|
|
24
|
+
__all__ = _ALL_LAZY.solveBase
|
|
25
|
+
__version__ = '24.03.15'
|
|
26
|
+
|
|
27
|
+
_ERROR_ = 'ERROR'
|
|
28
|
+
_text_True = dict() if _unlazy else dict(text=True)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _cmd_stdin_(cmd, stdin): # PYCHOK no cover
|
|
32
|
+
'''(INTERNAL) Cmd line, stdin and caller as sC{str}.
|
|
33
|
+
'''
|
|
34
|
+
c = Fmt.PAREN(callername(up=3))
|
|
35
|
+
t = (c,) if stdin is None else (_BACKSLASH_, str(stdin), c)
|
|
36
|
+
return _SPACE_.join(cmd + t)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _popen2(cmd, stdin=None): # in .mgrs, .test.base, .test.testMgrs
|
|
40
|
+
'''(INTERNAL) Invoke C{B{cmd} tuple} and return C{exitcode}
|
|
41
|
+
and all output to C{stdout/-err}.
|
|
42
|
+
'''
|
|
43
|
+
p = _Popen(cmd, creationflags=0,
|
|
44
|
+
# executable=sys.executable, shell=True,
|
|
45
|
+
stdin=_PIPE, stdout=_PIPE, stderr=_STDOUT,
|
|
46
|
+
**_text_True) # PYCHOK kwArgs
|
|
47
|
+
r = p.communicate(stdin)[0]
|
|
48
|
+
return p.returncode, ub2str(r).strip()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class _SolveLineSolveBase(_CapsBase):
|
|
52
|
+
'''(NTERNAL) Base class for C{_Solve} and C{_LineSolve}.
|
|
53
|
+
'''
|
|
54
|
+
_Error = None
|
|
55
|
+
_Exact = True
|
|
56
|
+
_invokation = 0
|
|
57
|
+
_Names_Direct = \
|
|
58
|
+
_Names_Inverse = ()
|
|
59
|
+
_prec = Precision_(prec=DIG)
|
|
60
|
+
_reverse2 = False
|
|
61
|
+
_Solve_name = NN # executable basename
|
|
62
|
+
_Solve_path = NN # executable path
|
|
63
|
+
_status = None
|
|
64
|
+
_unroll = False
|
|
65
|
+
_verbose = False
|
|
66
|
+
|
|
67
|
+
@property_RO
|
|
68
|
+
def _cmdBasic(self): # PYCHOK no cover
|
|
69
|
+
'''(INTERNAL) I{Must be overloaded}.'''
|
|
70
|
+
notOverloaded(self, underOK=True)
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def Exact(self):
|
|
74
|
+
'''Get the Solve's C{exact} setting (C{bool}).
|
|
75
|
+
'''
|
|
76
|
+
return self._Exact
|
|
77
|
+
|
|
78
|
+
@Exact.setter # PYCHOK setter!
|
|
79
|
+
def Exact(self, Exact):
|
|
80
|
+
'''Set the Solve's C{exact} setting (C{bool}),
|
|
81
|
+
if C{True} use I{exact} version.
|
|
82
|
+
'''
|
|
83
|
+
Exact = bool(Exact)
|
|
84
|
+
if self._Exact != Exact:
|
|
85
|
+
_update_all(self)
|
|
86
|
+
self._Exact = Exact
|
|
87
|
+
|
|
88
|
+
def _GDictInvoke(self, cmd, floats, Names, *args):
|
|
89
|
+
'''(INTERNAL) Invoke C{Solve}, return results as C{GDict}.
|
|
90
|
+
'''
|
|
91
|
+
N = len(Names)
|
|
92
|
+
if N < 1:
|
|
93
|
+
raise _AssertionError(cmd=cmd, Names=Names)
|
|
94
|
+
i = fstr(args, prec=DIG, fmt=Fmt.F, sep=_SPACE_) if args else None # not Fmt.G!
|
|
95
|
+
t = self._invoke(cmd, stdin=i).lstrip().split() # 12-/+ tuple
|
|
96
|
+
if len(t) > N: # PYCHOK no cover
|
|
97
|
+
# unzip instrumented name=value pairs to names and values
|
|
98
|
+
n, v = _zip(*(p.split(_EQUAL_) for p in t[:-N])) # strict=True
|
|
99
|
+
v += tuple(t[-N:])
|
|
100
|
+
n += Names
|
|
101
|
+
else:
|
|
102
|
+
n, v = Names, t
|
|
103
|
+
if self.verbose: # PYCHOK no cover
|
|
104
|
+
self._print(_COMMASPACE_.join(map(Fmt.EQUAL, n, map(fstrzs, v))))
|
|
105
|
+
if floats:
|
|
106
|
+
v = map(float, v)
|
|
107
|
+
r = GDict(_zip(n, v)) # strict=True
|
|
108
|
+
return self._iter2tion(r, r)
|
|
109
|
+
|
|
110
|
+
@property_RO
|
|
111
|
+
def invokation(self):
|
|
112
|
+
'''Get the most recent C{Solve} invokation number (C{int}).
|
|
113
|
+
'''
|
|
114
|
+
return self._invokation
|
|
115
|
+
|
|
116
|
+
def invoke(self, *options, **stdin):
|
|
117
|
+
'''Invoke the C{Solve} executable and return the result.
|
|
118
|
+
|
|
119
|
+
@arg options: No, one or several C{Solve} command line
|
|
120
|
+
options (C{str}s).
|
|
121
|
+
@kwarg stdin: Optional input to pass to C{Solve.stdin} (C{str}).
|
|
122
|
+
|
|
123
|
+
@return: The C{Solve.stdout} and C{.stderr} output (C{str}).
|
|
124
|
+
|
|
125
|
+
@raise GeodesicError: On any error, including a non-zero return
|
|
126
|
+
code from C{GeodSolve}.
|
|
127
|
+
|
|
128
|
+
@raise RhumbError: On any error, including a non-zero return code
|
|
129
|
+
from C{RhumbSolve}.
|
|
130
|
+
|
|
131
|
+
@note: The C{Solve} return code is in property L{status}.
|
|
132
|
+
'''
|
|
133
|
+
c = (self._Solve_path,) + map2(str, options)
|
|
134
|
+
i = _xkwds_get(stdin, stdin=None)
|
|
135
|
+
r = self._invoke(c, stdin=i)
|
|
136
|
+
s = self.status
|
|
137
|
+
if s:
|
|
138
|
+
raise self._Error(cmd=_cmd_stdin_(c, i), status=s,
|
|
139
|
+
txt=_not_(_0_))
|
|
140
|
+
if self.verbose: # PYCHOK no cover
|
|
141
|
+
self._print(r)
|
|
142
|
+
return r
|
|
143
|
+
|
|
144
|
+
def _invoke(self, cmd, stdin=None):
|
|
145
|
+
'''(INTERNAL) Invoke the C{Solve} executable, with the
|
|
146
|
+
given B{C{cmd}} line and optional input to B{C{stdin}}.
|
|
147
|
+
'''
|
|
148
|
+
self._invokation += 1
|
|
149
|
+
self._status = t = None
|
|
150
|
+
if self.verbose: # PYCHOK no cover
|
|
151
|
+
t = _cmd_stdin_(cmd, stdin)
|
|
152
|
+
self._print(t)
|
|
153
|
+
try: # invoke and write to stdin
|
|
154
|
+
s, r = _popen2(cmd, stdin)
|
|
155
|
+
if len(r) < 6 or r[:5] in (_Error_, _ERROR_):
|
|
156
|
+
raise ValueError(r)
|
|
157
|
+
except (IOError, OSError, TypeError, ValueError) as x:
|
|
158
|
+
raise self._Error(cmd=t or _cmd_stdin_(cmd, stdin), cause=x)
|
|
159
|
+
self._status = s
|
|
160
|
+
return r
|
|
161
|
+
|
|
162
|
+
@Property_RO
|
|
163
|
+
def _mpd(self): # meter per degree
|
|
164
|
+
return self.ellipsoid._Lpd
|
|
165
|
+
|
|
166
|
+
@property_RO
|
|
167
|
+
def _p_option(self):
|
|
168
|
+
return '-p', str(self.prec - 5) # -p is distance prec
|
|
169
|
+
|
|
170
|
+
@Property
|
|
171
|
+
def prec(self):
|
|
172
|
+
'''Get the precision, number of (decimal) digits (C{int}).
|
|
173
|
+
'''
|
|
174
|
+
return self._prec
|
|
175
|
+
|
|
176
|
+
@prec.setter # PYCHOK setter!
|
|
177
|
+
def prec(self, prec):
|
|
178
|
+
'''Set the precision for C{angles} in C{degrees}, like C{lat}, C{lon},
|
|
179
|
+
C{azimuth} and C{arc} in number of decimal digits (C{int}, C{0}..L{DIG}).
|
|
180
|
+
|
|
181
|
+
@note: The precision for C{distance = B{prec} - 5} or up to
|
|
182
|
+
10 decimal digits for C{nanometer} and for C{area =
|
|
183
|
+
B{prec} - 12} or at most C{millimeter} I{squared}.
|
|
184
|
+
'''
|
|
185
|
+
prec = Precision_(prec=prec, high=DIG)
|
|
186
|
+
if self._prec != prec:
|
|
187
|
+
_update_all(self)
|
|
188
|
+
self._prec = prec
|
|
189
|
+
|
|
190
|
+
def _print(self, line): # PYCHOK no cover
|
|
191
|
+
'''(INTERNAL) Print a status line.
|
|
192
|
+
'''
|
|
193
|
+
if self.status is not None:
|
|
194
|
+
line = _SPACE_(line, Fmt.PAREN(self.status))
|
|
195
|
+
printf('%s %d: %s', self.named2, self.invokation, line)
|
|
196
|
+
|
|
197
|
+
@Property
|
|
198
|
+
def reverse2(self):
|
|
199
|
+
'''Get the C{azi2} direction (C{bool}).
|
|
200
|
+
'''
|
|
201
|
+
return self._reverse2
|
|
202
|
+
|
|
203
|
+
@reverse2.setter # PYCHOK setter!
|
|
204
|
+
def reverse2(self, reverse2):
|
|
205
|
+
'''Set the direction for C{azi2} (C{bool}), if C{True} reverse C{azi2}.
|
|
206
|
+
'''
|
|
207
|
+
reverse2 = bool(reverse2)
|
|
208
|
+
if self._reverse2 != reverse2:
|
|
209
|
+
_update_all(self)
|
|
210
|
+
self._reverse2 = reverse2
|
|
211
|
+
|
|
212
|
+
def _setSolve(self, path, **Solve_path):
|
|
213
|
+
'''(INTERNAL) Set the executable C{path}.
|
|
214
|
+
'''
|
|
215
|
+
hold = self._Solve_path
|
|
216
|
+
if hold != path:
|
|
217
|
+
_update_all(self)
|
|
218
|
+
self._Solve_path = path
|
|
219
|
+
try:
|
|
220
|
+
_ = self.version # test path and ...
|
|
221
|
+
if self.status: # ... return code
|
|
222
|
+
S_p = Solve_path or {self._Solve_name: _enquote(path)}
|
|
223
|
+
raise self._Error(status=self.status, txt=_not_(_0_), **S_p)
|
|
224
|
+
hold = path
|
|
225
|
+
finally: # restore in case of error
|
|
226
|
+
if self._Solve_path != hold:
|
|
227
|
+
_update_all(self)
|
|
228
|
+
self._Solve_path = hold
|
|
229
|
+
|
|
230
|
+
@property_RO
|
|
231
|
+
def status(self):
|
|
232
|
+
'''Get the most recent C{Solve} return code (C{int}, C{str})
|
|
233
|
+
or C{None}.
|
|
234
|
+
'''
|
|
235
|
+
return self._status
|
|
236
|
+
|
|
237
|
+
@Property
|
|
238
|
+
def unroll(self):
|
|
239
|
+
'''Get the C{lon2} unroll'ing (C{bool}).
|
|
240
|
+
'''
|
|
241
|
+
return self._unroll
|
|
242
|
+
|
|
243
|
+
@unroll.setter # PYCHOK setter!
|
|
244
|
+
def unroll(self, unroll):
|
|
245
|
+
'''Set unroll'ing for C{lon2} (C{bool}), if C{True} unroll C{lon2}, otherwise don't.
|
|
246
|
+
'''
|
|
247
|
+
unroll = bool(unroll)
|
|
248
|
+
if self._unroll != unroll:
|
|
249
|
+
_update_all(self)
|
|
250
|
+
self._unroll = unroll
|
|
251
|
+
|
|
252
|
+
@property
|
|
253
|
+
def verbose(self):
|
|
254
|
+
'''Get the C{verbose} option (C{bool}).
|
|
255
|
+
'''
|
|
256
|
+
return self._verbose
|
|
257
|
+
|
|
258
|
+
@verbose.setter # PYCHOK setter!
|
|
259
|
+
def verbose(self, verbose):
|
|
260
|
+
'''Set the C{verbose} option (C{bool}), C{True} prints
|
|
261
|
+
a message around each C{RhumbSolve} invokation.
|
|
262
|
+
'''
|
|
263
|
+
self._verbose = bool(verbose)
|
|
264
|
+
|
|
265
|
+
@Property_RO
|
|
266
|
+
def version(self):
|
|
267
|
+
'''Get the result of C{"GeodSolve --version"} or C{"RhumbSolve --version"}.
|
|
268
|
+
'''
|
|
269
|
+
return self.invoke('--version')
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class _SolveBase(_SolveLineSolveBase):
|
|
273
|
+
'''(NTERNAL) Base class for C{_GeodesicSolveBase} and C{_RhumbSolveBase}.
|
|
274
|
+
'''
|
|
275
|
+
_datum = _WGS84
|
|
276
|
+
|
|
277
|
+
def __init__(self, a_ellipsoid=_EWGS84, f=None, path=NN, name=NN):
|
|
278
|
+
'''New C{Solve} instance.
|
|
279
|
+
|
|
280
|
+
@arg a_ellipsoid: An ellipsoid (L{Ellipsoid}) or datum (L{Datum}) or
|
|
281
|
+
the equatorial radius of the ellipsoid (C{scalar},
|
|
282
|
+
conventionally in C{meter}), see B{C{f}}.
|
|
283
|
+
@arg f: The flattening of the ellipsoid (C{scalar}) if B{C{a_ellipsoid}}
|
|
284
|
+
is specified as C{scalar}.
|
|
285
|
+
@kwarg path: Optionally, the (fully qualified) path to the C{GeodSolve}
|
|
286
|
+
or C{RhumbSolve} executable (C{filename}).
|
|
287
|
+
@kwarg name: Optional name (C{str}).
|
|
288
|
+
|
|
289
|
+
@raise TypeError: Invalid B{C{a_ellipsoid}} or B{C{f}}.
|
|
290
|
+
'''
|
|
291
|
+
_earth_datum(self, a_ellipsoid, f=f, name=name)
|
|
292
|
+
if name:
|
|
293
|
+
self.name = name
|
|
294
|
+
if path:
|
|
295
|
+
self._setSolve(path)
|
|
296
|
+
|
|
297
|
+
@Property_RO
|
|
298
|
+
def a(self):
|
|
299
|
+
'''Get the I{equatorial} radius, semi-axis (C{meter}).
|
|
300
|
+
'''
|
|
301
|
+
return self.ellipsoid.a
|
|
302
|
+
|
|
303
|
+
@Property_RO
|
|
304
|
+
def _cmdDirect(self):
|
|
305
|
+
'''(INTERNAL) Get the C{Solve} I{Direct} cmd (C{tuple}).
|
|
306
|
+
'''
|
|
307
|
+
return self._cmdBasic
|
|
308
|
+
|
|
309
|
+
@Property_RO
|
|
310
|
+
def _cmdInverse(self):
|
|
311
|
+
'''(INTERNAL) Get the C{Solve} I{Inverse} cmd (C{tuple}).
|
|
312
|
+
'''
|
|
313
|
+
return self._cmdBasic + ('-i',)
|
|
314
|
+
|
|
315
|
+
@property_RO
|
|
316
|
+
def datum(self):
|
|
317
|
+
'''Get the datum (C{Datum}).
|
|
318
|
+
'''
|
|
319
|
+
return self._datum
|
|
320
|
+
|
|
321
|
+
def Direct(self, lat1, lon1, azi1, s12, outmask=_UNUSED_): # PYCHOK unused
|
|
322
|
+
'''Return the C{Direct} result.
|
|
323
|
+
'''
|
|
324
|
+
return self._GDictDirect(lat1, lon1, azi1, False, s12)
|
|
325
|
+
|
|
326
|
+
@Property_RO
|
|
327
|
+
def ellipsoid(self):
|
|
328
|
+
'''Get the ellipsoid (C{Ellipsoid}).
|
|
329
|
+
'''
|
|
330
|
+
return self.datum.ellipsoid
|
|
331
|
+
|
|
332
|
+
@Property_RO
|
|
333
|
+
def _e_option(self):
|
|
334
|
+
E = self.ellipsoid
|
|
335
|
+
if E is _EWGS84:
|
|
336
|
+
return () # default
|
|
337
|
+
a, f = strs(E.a_f, fmt=Fmt.F, prec=DIG + 3) # not .G!
|
|
338
|
+
return ('-e', a, f)
|
|
339
|
+
|
|
340
|
+
@Property_RO
|
|
341
|
+
def flattening(self):
|
|
342
|
+
'''Get the C{ellipsoid}'s I{flattening} (C{scalar}), M{(a - b) / a},
|
|
343
|
+
C{0} for spherical, negative for prolate.
|
|
344
|
+
'''
|
|
345
|
+
return self.ellipsoid.f
|
|
346
|
+
|
|
347
|
+
f = flattening
|
|
348
|
+
|
|
349
|
+
def _GDictDirect(self, lat, lon, azi, arcmode, s12_a12, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
|
|
350
|
+
'''(INTERNAL) Get C{_GenDirect}-like result as C{GDict}.
|
|
351
|
+
'''
|
|
352
|
+
if arcmode:
|
|
353
|
+
raise self._Error(arcmode=arcmode, txt=str(NotImplemented))
|
|
354
|
+
floats = _xkwds_get(floats, floats=True)
|
|
355
|
+
return self._GDictInvoke(self._cmdDirect, floats, self._Names_Direct,
|
|
356
|
+
lat, lon, azi, s12_a12)
|
|
357
|
+
|
|
358
|
+
def _GDictInverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_, **floats): # PYCHOK for .geodesicx.gxarea
|
|
359
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as C{GDict}, but
|
|
360
|
+
I{without} C{_SALPs_CALPs_}.
|
|
361
|
+
'''
|
|
362
|
+
floats = _xkwds_get(floats, floats=True)
|
|
363
|
+
return self._GDictInvoke(self._cmdInverse, floats, self._Names_Inverse,
|
|
364
|
+
lat1, lon1, lat2, lon2)
|
|
365
|
+
|
|
366
|
+
def Inverse(self, lat1, lon1, lat2, lon2, outmask=_UNUSED_): # PYCHOK unused
|
|
367
|
+
'''Return the C{Inverse} result.
|
|
368
|
+
'''
|
|
369
|
+
return self._GDictInverse(lat1, lon1, lat2, lon2)
|
|
370
|
+
|
|
371
|
+
def Inverse1(self, lat1, lon1, lat2, lon2, wrap=False):
|
|
372
|
+
'''Return the non-negative, I{angular} distance in C{degrees}.
|
|
373
|
+
'''
|
|
374
|
+
# see .FrechetKarney.distance, .HausdorffKarney._distance
|
|
375
|
+
# and .HeightIDWkarney._distances
|
|
376
|
+
_, lon2 = unroll180(lon1, lon2, wrap=wrap) # self.LONG_UNROLL
|
|
377
|
+
r = self._GDictInverse(lat1, lon1, lat2, lon2, floats=False)
|
|
378
|
+
# XXX self.DISTANCE needed for 'a12'?
|
|
379
|
+
return abs(float(r.a12))
|
|
380
|
+
|
|
381
|
+
def _toStr(self, prec=6, sep=_COMMASPACE_, **Solve): # PYCHOK signature
|
|
382
|
+
'''(INTERNAL) Return this C{_Solve} as string..
|
|
383
|
+
'''
|
|
384
|
+
d = dict(ellipsoid=self.ellipsoid, invokation=self.invokation,
|
|
385
|
+
status=self.status, **Solve)
|
|
386
|
+
return sep.join(pairs(d, prec=prec))
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class _SolveLineBase(_SolveLineSolveBase):
|
|
390
|
+
'''(NTERNAL) Base class for C{GeodesicLineSolve} and C{RhumbLineSolve}.
|
|
391
|
+
'''
|
|
392
|
+
# _caps = 0
|
|
393
|
+
# _lla1 = {}
|
|
394
|
+
_solve = None # L{GeodesicSolve} or L{RhumbSolve} instance
|
|
395
|
+
|
|
396
|
+
def __init__(self, solve, lat1, lon1, caps, name, **azi):
|
|
397
|
+
self._caps = caps | Caps._LINE
|
|
398
|
+
self._debug = solve._debug & Caps._DEBUG_ALL
|
|
399
|
+
self._lla1 = GDict(lat1=lat1, lon1=lon1, **azi)
|
|
400
|
+
self._solve = solve
|
|
401
|
+
|
|
402
|
+
n = name or solve.name
|
|
403
|
+
if n:
|
|
404
|
+
self.name = n
|
|
405
|
+
|
|
406
|
+
@Property_RO
|
|
407
|
+
def _cmdDistance(self):
|
|
408
|
+
'''(INTERNAL) Get the C{GeodSolve} I{-L} cmd (C{tuple}).
|
|
409
|
+
'''
|
|
410
|
+
def _lla3(lat1=0, lon1=0, **azi):
|
|
411
|
+
_, azi = _xkwds_item2(azi)
|
|
412
|
+
return lat1, lon1, azi
|
|
413
|
+
|
|
414
|
+
t = strs(_lla3(**self._lla1), prec=DIG, fmt=Fmt.F) # self._solve.prec
|
|
415
|
+
return self._cmdBasic + ('-L',) + t
|
|
416
|
+
|
|
417
|
+
@property_RO
|
|
418
|
+
def datum(self):
|
|
419
|
+
'''Get the datum (C{Datum}).
|
|
420
|
+
'''
|
|
421
|
+
return self._solve.datum
|
|
422
|
+
|
|
423
|
+
@property_RO
|
|
424
|
+
def ellipsoid(self):
|
|
425
|
+
'''Get the ellipsoid (C{Ellipsoid}).
|
|
426
|
+
'''
|
|
427
|
+
return self._solve.ellipsoid
|
|
428
|
+
|
|
429
|
+
@Property_RO
|
|
430
|
+
def lat1(self):
|
|
431
|
+
'''Get the latitude of the first point (C{degrees}).
|
|
432
|
+
'''
|
|
433
|
+
return self._lla1.lat1
|
|
434
|
+
|
|
435
|
+
@Property_RO
|
|
436
|
+
def lon1(self):
|
|
437
|
+
'''Get the longitude of the first point (C{degrees}).
|
|
438
|
+
'''
|
|
439
|
+
return self._lla1.lon1
|
|
440
|
+
|
|
441
|
+
def _toStr(self, prec=6, sep=_COMMASPACE_, **solve): # PYCHOK signature
|
|
442
|
+
'''(INTERNAL) Return this C{_LineSolve} as string..
|
|
443
|
+
'''
|
|
444
|
+
d = dict(ellipsoid=self.ellipsoid, invokation=self._solve.invokation,
|
|
445
|
+
lat1=self.lat1, lon1=self.lon1,
|
|
446
|
+
status=self._solve.status, **solve)
|
|
447
|
+
return sep.join(pairs(d, prec=prec))
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
__all__ += _ALL_DOCS(_SolveBase, _SolveLineBase, _SolveLineSolveBase)
|
|
451
|
+
|
|
452
|
+
# **) MIT License
|
|
453
|
+
#
|
|
454
|
+
# Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
455
|
+
#
|
|
456
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
457
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
458
|
+
# to deal in the Software without restriction, including without limitation
|
|
459
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
460
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
461
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
462
|
+
#
|
|
463
|
+
# The above copyright notice and this permission notice shall be included
|
|
464
|
+
# in all copies or substantial portions of the Software.
|
|
465
|
+
#
|
|
466
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
467
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
468
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
469
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
470
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
471
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
472
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|