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/geodsolve.py
CHANGED
|
@@ -10,48 +10,31 @@ of the C{GeodSolve} executable.
|
|
|
10
10
|
'''
|
|
11
11
|
|
|
12
12
|
from pygeodesy.basics import _xinstanceof
|
|
13
|
-
# from pygeodesy.constants import NAN, _0_0
|
|
13
|
+
# from pygeodesy.constants import NAN, _0_0 # from .karney
|
|
14
14
|
# from pygeodesy.geodesicx import GeodesicAreaExact # _MODS
|
|
15
|
-
from pygeodesy.interns import NN,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
from pygeodesy.interns import _UNUSED_, _not_ # PYCHOK used!
|
|
19
|
-
from pygeodesy.karney import _Azi, Caps, _Deg, GeodesicError, _GTuple, \
|
|
20
|
-
_Pass, _Lat, _Lon, _M, _M2, _sincos2d, \
|
|
21
|
-
_0_0, NAN
|
|
15
|
+
from pygeodesy.interns import NN, _UNDER_
|
|
16
|
+
from pygeodesy.karney import Caps, GeodesicError, GeodSolve12Tuple, \
|
|
17
|
+
_llz2line, _sincos2d, _0_0, NAN
|
|
22
18
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
23
19
|
_getenv, _PYGEODESY_GEODSOLVE_
|
|
24
20
|
from pygeodesy.named import _name1__
|
|
25
21
|
from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
|
|
26
22
|
from pygeodesy.props import Property, Property_RO, property_RO
|
|
27
|
-
from pygeodesy.solveBase import
|
|
23
|
+
from pygeodesy.solveBase import _SolveGDictBase, _SolveGDictLineBase
|
|
28
24
|
from pygeodesy.utily import _unrollon, _Wrap, wrap360
|
|
29
25
|
|
|
30
26
|
__all__ = _ALL_LAZY.geodsolve
|
|
31
|
-
__version__ = '24.
|
|
27
|
+
__version__ = '24.07.09'
|
|
32
28
|
|
|
33
29
|
|
|
34
|
-
class
|
|
35
|
-
'''12-Tuple C{(lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12)} with
|
|
36
|
-
angles C{lat1}, C{lon1}, C{azi1}, C{lat2}, C{lon2} and C{azi2} and arc C{a12} all in
|
|
37
|
-
C{degrees}, initial C{azi1} and final C{azi2} forward azimuths, distance C{s12} and
|
|
38
|
-
reduced length C{m12} in C{meter}, area C{S12} in C{meter} I{squared} and geodesic
|
|
39
|
-
scale factors C{M12} and C{M21}, both C{scalar}, see U{GeodSolve
|
|
40
|
-
<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}.
|
|
41
|
-
'''
|
|
42
|
-
# from GeodSolve --help option -f ... lat1 lon1 azi1 lat2 lon2 azi2 s12 a12 m12 M12 M21 S12
|
|
43
|
-
_Names_ = (_lat1_, _lon1_, _azi1_, _lat2_, _lon2_, _azi2_, _s12_, _a12_, _m12_, _M12_, _M21_, _S12_)
|
|
44
|
-
_Units_ = (_Lat, _Lon, _Azi, _Lat, _Lon, _Azi, _M, _Deg, _Pass, _Pass, _Pass, _M2)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class _GeodesicSolveBase(_SolveBase):
|
|
30
|
+
class _GeodesicSolveBase(_SolveGDictBase):
|
|
48
31
|
'''(INTERNAL) Base class for L{GeodesicSolve} and L{GeodesicLineSolve}.
|
|
49
32
|
'''
|
|
50
33
|
_Error = GeodesicError
|
|
51
34
|
_Names_Direct = \
|
|
52
35
|
_Names_Inverse = GeodSolve12Tuple._Names_
|
|
53
|
-
|
|
54
|
-
|
|
36
|
+
_Xable_name = 'GeodSolve'
|
|
37
|
+
_Xable_path = _getenv(_PYGEODESY_GEODSOLVE_, _PYGEODESY_GEODSOLVE_)
|
|
55
38
|
|
|
56
39
|
@Property_RO
|
|
57
40
|
def _b_option(self):
|
|
@@ -67,16 +50,12 @@ class _GeodesicSolveBase(_SolveBase):
|
|
|
67
50
|
self._p_option +
|
|
68
51
|
self._u_option)
|
|
69
52
|
|
|
70
|
-
@Property_RO
|
|
71
|
-
def _E_option(self):
|
|
72
|
-
return ('-E',) if self.Exact else ()
|
|
73
|
-
|
|
74
53
|
@Property
|
|
75
54
|
def GeodSolve(self):
|
|
76
55
|
'''Get the U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}
|
|
77
56
|
executable (C{filename}).
|
|
78
57
|
'''
|
|
79
|
-
return self.
|
|
58
|
+
return self._Xable_path
|
|
80
59
|
|
|
81
60
|
@GeodSolve.setter # PYCHOK setter!
|
|
82
61
|
def GeodSolve(self, path):
|
|
@@ -86,20 +65,20 @@ class _GeodesicSolveBase(_SolveBase):
|
|
|
86
65
|
@raise GeodesicError: Invalid B{C{path}}, B{C{path}} doesn't exist or
|
|
87
66
|
isn't the C{GeodSolve} executable.
|
|
88
67
|
'''
|
|
89
|
-
self.
|
|
68
|
+
self._setXable(path)
|
|
90
69
|
|
|
91
70
|
def toStr(self, **prec_sep): # PYCHOK signature
|
|
92
71
|
'''Return this C{GeodesicSolve} as string.
|
|
93
72
|
|
|
94
|
-
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
73
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
|
|
74
|
+
for the C{float} C{prec}ision, number of decimal digits
|
|
75
|
+
(0..9) and the C{sep}arator string to join. Trailing
|
|
76
|
+
zero decimals are stripped for B{C{prec}} values of 1
|
|
77
|
+
and above, but kept for negative B{C{prec}} values.
|
|
99
78
|
|
|
100
79
|
@return: GeodesicSolve items (C{str}).
|
|
101
80
|
'''
|
|
102
|
-
return
|
|
81
|
+
return _SolveGDictBase._toStr(self, GeodSolve=self.GeodSolve, **prec_sep)
|
|
103
82
|
|
|
104
83
|
@Property_RO
|
|
105
84
|
def _u_option(self):
|
|
@@ -119,11 +98,11 @@ class GeodesicSolve(_GeodesicSolveBase):
|
|
|
119
98
|
'''
|
|
120
99
|
|
|
121
100
|
def Area(self, polyline=False, **name):
|
|
122
|
-
'''Set up a L{GeodesicAreaExact} to compute area and
|
|
123
|
-
|
|
101
|
+
'''Set up a L{GeodesicAreaExact} to compute area and perimeter
|
|
102
|
+
of a polygon.
|
|
124
103
|
|
|
125
|
-
@kwarg polyline: If C{True} perimeter only, otherwise
|
|
126
|
-
|
|
104
|
+
@kwarg polyline: If C{True} perimeter only, otherwise area
|
|
105
|
+
and perimeter (C{bool}).
|
|
127
106
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
128
107
|
|
|
129
108
|
@return: A L{GeodesicAreaExact} instance.
|
|
@@ -139,8 +118,8 @@ class GeodesicSolve(_GeodesicSolveBase):
|
|
|
139
118
|
Polygon = Area # for C{geographiclib} compatibility
|
|
140
119
|
|
|
141
120
|
def Direct3(self, lat1, lon1, azi1, s12): # PYCHOK outmask
|
|
142
|
-
'''Return the destination lat, lon and reverse azimuth
|
|
143
|
-
|
|
121
|
+
'''Return the destination lat, lon and reverse azimuth (final bearing)
|
|
122
|
+
in C{degrees}.
|
|
144
123
|
|
|
145
124
|
@return: L{Destination3Tuple}C{(lat, lon, final)}.
|
|
146
125
|
'''
|
|
@@ -228,10 +207,10 @@ class GeodesicSolve(_GeodesicSolveBase):
|
|
|
228
207
|
gl = GeodesicLineSolve(self, lat1, lon1, r.azi1, **_name1__(caps_name, _or_nameof=self))
|
|
229
208
|
gl._a13 = r.a12 # gl.SetArc(r.a12)
|
|
230
209
|
gl._s13 = r.s12 # gl.SetDistance(r.s12)
|
|
231
|
-
return gl
|
|
210
|
+
return _llz2line(gl, lat2=lat2, lon2=lon2, azi2=r.azi2)
|
|
232
211
|
|
|
233
212
|
|
|
234
|
-
class GeodesicLineSolve(_GeodesicSolveBase,
|
|
213
|
+
class GeodesicLineSolve(_GeodesicSolveBase, _SolveGDictLineBase):
|
|
235
214
|
'''Wrapper to invoke I{Karney}'s U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}
|
|
236
215
|
as an C{Exact} version of I{Karney}'s Python class U{GeodesicLine<https://GeographicLib.SourceForge.io/C++/doc/
|
|
237
216
|
python/code.html#geographiclib.geodesicline.GeodesicLine>}.
|
|
@@ -269,7 +248,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
269
248
|
_xinstanceof(GeodesicSolve, geodesic=geodesic)
|
|
270
249
|
if (caps & Caps.LINE_OFF): # copy to avoid updates
|
|
271
250
|
geodesic = geodesic.copy(deep=False, name=_UNDER_(NN, geodesic.name)) # NOT _under!
|
|
272
|
-
|
|
251
|
+
_SolveGDictLineBase.__init__(self, geodesic, lat1, lon1, caps, azi1=azi1, **name)
|
|
273
252
|
try:
|
|
274
253
|
self.GeodSolve = geodesic.GeodSolve # geodesic or copy of geodesic
|
|
275
254
|
except GeodesicError:
|
|
@@ -299,7 +278,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
299
278
|
@return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
|
|
300
279
|
azi2, m12, a12, s12, M12, M21, S12}.
|
|
301
280
|
'''
|
|
302
|
-
return self._GDictInvoke(self._cmdArc,
|
|
281
|
+
return self._GDictInvoke(self._cmdArc, self._Names_Direct, a12)._unCaps(outmask)
|
|
303
282
|
|
|
304
283
|
@Property_RO
|
|
305
284
|
def azi1(self):
|
|
@@ -350,7 +329,7 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
350
329
|
@return: A C{GDict} with 12 items C{lat1, lon1, azi1, lat2, lon2,
|
|
351
330
|
azi2, m12, a12, s12, M12, M21, S12}, possibly C{a12=NAN}.
|
|
352
331
|
'''
|
|
353
|
-
return self._GDictInvoke(self._cmdDistance,
|
|
332
|
+
return self._GDictInvoke(self._cmdDistance, self._Names_Direct, s12)._unCaps(outmask)
|
|
354
333
|
|
|
355
334
|
@Property_RO
|
|
356
335
|
def s13(self):
|
|
@@ -392,16 +371,16 @@ class GeodesicLineSolve(_GeodesicSolveBase, _SolveLineBase):
|
|
|
392
371
|
def toStr(self, **prec_sep): # PYCHOK signature
|
|
393
372
|
'''Return this C{GeodesicLineSolve} as string.
|
|
394
373
|
|
|
395
|
-
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
374
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=", "}
|
|
375
|
+
for the C{float} C{prec}ision, number of decimal digits
|
|
376
|
+
(0..9) and the C{sep}arator string to join. Trailing
|
|
377
|
+
zero decimals are stripped for B{C{prec}} values of 1
|
|
378
|
+
and above, but kept for negative B{C{prec}} values.
|
|
400
379
|
|
|
401
380
|
@return: GeodesicLineSolve items (C{str}).
|
|
402
381
|
'''
|
|
403
|
-
return
|
|
404
|
-
|
|
382
|
+
return _SolveGDictLineBase._toStr(self, azi1=self.azi1, geodesic=self._solve,
|
|
383
|
+
GeodSolve=self.GeodSolve, **prec_sep)
|
|
405
384
|
|
|
406
385
|
|
|
407
386
|
__all__ += _ALL_DOCS(_GeodesicSolveBase)
|
|
@@ -415,7 +394,7 @@ if __name__ == '__main__':
|
|
|
415
394
|
gS.verbose = '--verbose' in argv # or '-v' in argv
|
|
416
395
|
|
|
417
396
|
if gS.GeodSolve in (_PYGEODESY_GEODSOLVE_, None): # not set
|
|
418
|
-
gS.GeodSolve = '/opt/local/bin/GeodSolve' # '/opt/local/Cellar/geographiclib/
|
|
397
|
+
gS.GeodSolve = '/opt/local/bin/GeodSolve' # '/opt/local/Cellar/geographiclib/2.3/bin/GeodSolve' # HomeBrew
|
|
419
398
|
printf('version: %s', gS.version)
|
|
420
399
|
|
|
421
400
|
r = gS.Direct(40.6, -73.8, 51, 5.5e6)
|
pygeodesy/internals.py
CHANGED
|
@@ -4,9 +4,9 @@ u'''Mostly INTERNAL functions, except L{machine}, L{print_} and L{printf}.
|
|
|
4
4
|
'''
|
|
5
5
|
# from pygeodesy.basics import isiterablen # _MODS
|
|
6
6
|
# from pygeodesy.errors import _AttributeError, _error_init, _UnexpectedError, _xError2 # _MODS
|
|
7
|
-
from pygeodesy.interns import NN, _COLON_, _DOT_, _ELLIPSIS_, _EQUALSPACED_, \
|
|
8
|
-
_immutable_, _NL_, _pygeodesy_, _PyPy__, _python_, \
|
|
9
|
-
|
|
7
|
+
from pygeodesy.interns import NN, _BAR_, _COLON_, _DASH_, _DOT_, _ELLIPSIS_, _EQUALSPACED_, \
|
|
8
|
+
_immutable_, _NL_, _pygeodesy_, _PyPy__, _python_, _QUOTE1_, \
|
|
9
|
+
_QUOTE2_, _s_, _SPACE_, _sys, _UNDER_, _utf_8_
|
|
10
10
|
from pygeodesy.interns import _COMMA_, _Python_ # PYCHOK used!
|
|
11
11
|
# from pygeodesy.streprs import anstr, pairs, unstr # _MODS
|
|
12
12
|
|
|
@@ -360,10 +360,10 @@ def _passargs(*args):
|
|
|
360
360
|
return args
|
|
361
361
|
|
|
362
362
|
|
|
363
|
-
def _plural(noun, n):
|
|
363
|
+
def _plural(noun, n, nn=NN):
|
|
364
364
|
'''(INTERNAL) Return C{noun}['s'] or C{NN}.
|
|
365
365
|
'''
|
|
366
|
-
return NN(noun, _s_) if n > 1 else (noun if n else
|
|
366
|
+
return NN(noun, _s_) if n > 1 else (noun if n else nn)
|
|
367
367
|
|
|
368
368
|
|
|
369
369
|
def print_(*args, **nl_nt_prec_prefix__end_file_flush_sep__kwds): # PYCHOK no cover
|
|
@@ -504,17 +504,44 @@ def _under(name): # PYCHOK in .datums, .auxilats, .ups, .utm, .utmupsBase, ...
|
|
|
504
504
|
return name if name.startswith(_UNDER_) else NN(_UNDER_, name)
|
|
505
505
|
|
|
506
506
|
|
|
507
|
-
def _usage(file_py, *args): # in .etm
|
|
507
|
+
def _usage(file_py, *args, **opts_help): # in .etm, .geodesici
|
|
508
508
|
'''(INTERNAL) Build "usage: python -m ..." cmd line for module B{C{file_py}}.
|
|
509
509
|
'''
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
510
|
+
if opts_help:
|
|
511
|
+
|
|
512
|
+
def _help(alts=(), help=NN, **unused):
|
|
513
|
+
if alts and help:
|
|
514
|
+
h = NN(help, _SPACE_).lstrip(_DASH_)
|
|
515
|
+
for a in alts:
|
|
516
|
+
if a.startswith(h):
|
|
517
|
+
return NN(_DASH_, a),
|
|
518
|
+
|
|
519
|
+
def _opts(opts=NN, alts=(), **unused):
|
|
520
|
+
# opts='T--v-C-R meter-c|i|n|o'
|
|
521
|
+
d, fmt = NN, _MODS.streprs.Fmt.SQUARE
|
|
522
|
+
for o in (opts + _BAR_(*alts)).split(_DASH_):
|
|
523
|
+
if o:
|
|
524
|
+
yield fmt(NN(d, _DASH_, o.replace(_BAR_, ' | -')))
|
|
525
|
+
d = NN
|
|
526
|
+
else:
|
|
527
|
+
d = _DASH_
|
|
528
|
+
|
|
529
|
+
args = _help(**opts_help) or (tuple(_opts(**opts_help)) + args)
|
|
530
|
+
|
|
531
|
+
u = _COLON_(_dunder_nameof(_usage)[1:], NN)
|
|
532
|
+
return _SPACE_(u, *_usage_argv(file_py, *args))
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
def _usage_argv(argv0, *args):
|
|
536
|
+
'''(INTERNAL) Return 3-tuple C{(python, '-m', module, *args)}.
|
|
537
|
+
'''
|
|
538
|
+
m = _os_path.dirname(argv0).replace(_os.getcwd(), _ELLIPSIS_) \
|
|
539
|
+
.replace(_os.sep, _DOT_).strip()
|
|
540
|
+
b, x = _os_path.splitext(_os_path.basename(argv0))
|
|
513
541
|
if x == '.py' and not _dunder_ismain(b):
|
|
514
542
|
m = _DOT_(m or _pygeodesy_, b)
|
|
515
|
-
p =
|
|
516
|
-
|
|
517
|
-
return _SPACE_(u, p, '-m', _enquote(m), *args)
|
|
543
|
+
p = NN(_python_, _sys.version_info[0])
|
|
544
|
+
return (p, '-m', _enquote(m)) + args
|
|
518
545
|
|
|
519
546
|
|
|
520
547
|
def _version2(version, n=2):
|
|
@@ -550,7 +577,7 @@ def _version_ints(vs):
|
|
|
550
577
|
|
|
551
578
|
|
|
552
579
|
__all__ = tuple(map(_dunder_nameof, (machine, print_, printf)))
|
|
553
|
-
__version__ = '24.
|
|
580
|
+
__version__ = '24.07.04'
|
|
554
581
|
|
|
555
582
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
556
583
|
|
pygeodesy/karney.py
CHANGED
|
@@ -143,13 +143,14 @@ from pygeodesy.basics import _copysign, int1s, isint, itemsorted, neg, unsigned0
|
|
|
143
143
|
_xgeographiclib, _zip, _version_info
|
|
144
144
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
|
|
145
145
|
_1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
146
|
-
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
|
|
146
|
+
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1, \
|
|
147
|
+
_xkwds_kwds, _xkwds_not
|
|
147
148
|
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
148
149
|
# from pygeodesy.internals import _version_info # from .basics
|
|
149
|
-
from pygeodesy.interns import _2_, _a12_, _area_, _azi2_, _azi12_,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
151
|
+
_composite_, _lat1_, _lat2_, _lon1_, _lon2_, \
|
|
152
|
+
_m12_, _M12_, _M21_, _number_, _s12_, _S12_, \
|
|
153
|
+
_UNDER_, _X_, _BAR_ # PYCHOK used!
|
|
153
154
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
154
155
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
155
156
|
from pygeodesy.props import deprecated_method, Property_RO
|
|
@@ -160,7 +161,7 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
160
161
|
# from math import fabs # from .utily
|
|
161
162
|
|
|
162
163
|
__all__ = _ALL_LAZY.karney
|
|
163
|
-
__version__ = '24.
|
|
164
|
+
__version__ = '24.07.09'
|
|
164
165
|
|
|
165
166
|
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
|
|
166
167
|
_perimeter_ = 'perimeter'
|
|
@@ -211,10 +212,10 @@ class Caps(object): # PYCHOK
|
|
|
211
212
|
'''(INTERNAL) Overriden by C{Caps} below.
|
|
212
213
|
'''
|
|
213
214
|
EMPTY = 0 # formerly aka NONE
|
|
214
|
-
_CAP_1 = 1 << 0 # for
|
|
215
|
-
_CAP_1p = 1 << 1 # for
|
|
215
|
+
_CAP_1 = 1 << 0 # for goedesici/-w
|
|
216
|
+
_CAP_1p = 1 << 1 # for goedesici/-w
|
|
216
217
|
_CAP_2 = 1 << 2
|
|
217
|
-
_CAP_3 = 1 << 3 # for
|
|
218
|
+
_CAP_3 = 1 << 3 # for goedesici/-w
|
|
218
219
|
# _CAP_4 = 1 << 4
|
|
219
220
|
# _CAP_ALL = 0x1F
|
|
220
221
|
# _CAP_MASK = _CAP_ALL
|
|
@@ -233,7 +234,7 @@ class Caps(object): # PYCHOK
|
|
|
233
234
|
_DIRECT3 = AZIMUTH | LATITUDE | LONGITUDE | _CAP_3 # for goedesicw only
|
|
234
235
|
_INVERSE3 = AZIMUTH | DISTANCE | _CAP_1 # for goedesicw only
|
|
235
236
|
_STD = STANDARD | _CAP_3 | _CAP_1 # for goedesicw only
|
|
236
|
-
_STD_LINE = _STD | _CAP_2 | _CAP_1p # for goedesici
|
|
237
|
+
_STD_LINE = _STD | _CAP_2 | _CAP_1p # for goedesici/-w
|
|
237
238
|
|
|
238
239
|
LINE_CAPS = _STD_LINE | REDUCEDLENGTH | GEODESICSCALE # .geodesici only
|
|
239
240
|
|
|
@@ -248,14 +249,14 @@ class Caps(object): # PYCHOK
|
|
|
248
249
|
AZIMUTH_DISTANCE_AREA = AZIMUTH | DISTANCE | AREA
|
|
249
250
|
|
|
250
251
|
_ANGLE_ONLY = 1 << 18 # angular distance C{a12} only
|
|
251
|
-
|
|
252
|
+
_S_CALPs_ = 1 << 19 # (INTERNAL) GeodesicExact._GenInverse
|
|
252
253
|
|
|
253
254
|
_DEBUG_AREA = 1 << 20 # (INTERNAL) include Line details
|
|
254
255
|
_DEBUG_DIRECT = 1 << 21 # (INTERNAL) include Direct details
|
|
255
256
|
_DEBUG_INVERSE = 1 << 22 # (INTERNAL) include Inverse details
|
|
256
257
|
_DEBUG_LINE = 1 << 23 # (INTERNAL) include Line details
|
|
257
258
|
_DEBUG_ALL = _DEBUG_AREA | _DEBUG_DIRECT | _DEBUG_INVERSE | \
|
|
258
|
-
_DEBUG_LINE | _ANGLE_ONLY |
|
|
259
|
+
_DEBUG_LINE | _ANGLE_ONLY | _S_CALPs_
|
|
259
260
|
|
|
260
261
|
_OUT_ALL = ALL
|
|
261
262
|
_OUT_MASK = ALL | LONG_UNROLL | REVERSE2 | _DEBUG_ALL
|
|
@@ -273,7 +274,7 @@ class Caps(object): # PYCHOK
|
|
|
273
274
|
s = []
|
|
274
275
|
for c, C in itemsorted(self.__class__.__dict__):
|
|
275
276
|
if isint(C) and (Csk & C) and int1s(C) == 1 \
|
|
276
|
-
and (C in (Caps.REVERSE2, Caps.
|
|
277
|
+
and (C in (Caps.REVERSE2, Caps._S_CALPs_)
|
|
277
278
|
or c.replace(_UNDER_, NN).isupper()):
|
|
278
279
|
s.append(c)
|
|
279
280
|
return sep.join(s) if sep else tuple(s)
|
|
@@ -310,9 +311,14 @@ and C{ALL} - all of the above.
|
|
|
310
311
|
|
|
311
312
|
C{STANDARD} = C{AZIMUTH | DISTANCE | DISTANCE_IN | LATITUDE | LONGITUDE}'''
|
|
312
313
|
|
|
313
|
-
_KEY2Caps = dict(
|
|
314
|
-
|
|
315
|
-
|
|
314
|
+
_KEY2Caps = dict(azi2=Caps.AZIMUTH, # see GDict._unCaps
|
|
315
|
+
lat2=Caps.LATITUDE,
|
|
316
|
+
lon2=Caps.LONGITUDE,
|
|
317
|
+
m12 =Caps.REDUCEDLENGTH,
|
|
318
|
+
M12 =Caps.GEODESICSCALE,
|
|
319
|
+
M21 =Caps.GEODESICSCALE,
|
|
320
|
+
s12 =Caps.DISTANCE,
|
|
321
|
+
S12 =Caps.AREA)
|
|
316
322
|
|
|
317
323
|
|
|
318
324
|
class _CapsBase(_NamedBase): # in .auxilats, .geodesicx.gxbases
|
|
@@ -426,6 +432,12 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
426
432
|
'''
|
|
427
433
|
return self._toTuple(Inverse10Tuple, dflt)
|
|
428
434
|
|
|
435
|
+
def _toNAN(self, outmask): # .GeodesicLineExact._GenPosition
|
|
436
|
+
'''(INTERNAL) Convert this C{GDict} to all C{NAN}s.
|
|
437
|
+
'''
|
|
438
|
+
d = dict((n, NAN) for n in GeodSolve12Tuple._Names_)
|
|
439
|
+
return self.set_(**d)._unCaps(outmask)
|
|
440
|
+
|
|
429
441
|
@deprecated_method
|
|
430
442
|
def toRhumb7Tuple(self, dflt=NAN): # PYCHOK no cover
|
|
431
443
|
'''DEPRECATED on 23.12.07, use method C{toRhumb8Tuple}.
|
|
@@ -461,6 +473,18 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
461
473
|
t = tuple(_g(self, n, dflt) for n in nTuple._Names_)
|
|
462
474
|
return nTuple(t, iteration=self._iteration)
|
|
463
475
|
|
|
476
|
+
def _2X(self, gl, _2X=_X_): # .Intesectool, .Intersector
|
|
477
|
+
'''(INTERNAL) Rename attr tail from C{-2} to C{-X} or C{-M}.
|
|
478
|
+
'''
|
|
479
|
+
X = GDict(self)
|
|
480
|
+
for n in (_lat2_, _lon2_, _azi2_, _s12_, _a12_):
|
|
481
|
+
if n in X: # X._X = X._2
|
|
482
|
+
X[n[:-1] + _2X] = X.pop(n)
|
|
483
|
+
v = getattr(gl, n, X)
|
|
484
|
+
if v is not X: # X._2 = gl._2
|
|
485
|
+
X[n] = v
|
|
486
|
+
return X
|
|
487
|
+
|
|
464
488
|
def _unCaps(self, outmask): # in .geodsolve
|
|
465
489
|
'''(INTERNAL) Remove superfluous items.
|
|
466
490
|
'''
|
|
@@ -470,6 +494,19 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
470
494
|
return self
|
|
471
495
|
|
|
472
496
|
|
|
497
|
+
class GeodSolve12Tuple(_GTuple):
|
|
498
|
+
'''12-Tuple C{(lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12)} with
|
|
499
|
+
angles C{lat1}, C{lon1}, C{azi1}, C{lat2}, C{lon2} and C{azi2} and arc C{a12} all in
|
|
500
|
+
C{degrees}, initial C{azi1} and final C{azi2} forward azimuths, distance C{s12} and
|
|
501
|
+
reduced length C{m12} in C{meter}, area C{S12} in C{meter} I{squared} and geodesic
|
|
502
|
+
scale factors C{M12} and C{M21}, both C{scalar}, see U{GeodSolve
|
|
503
|
+
<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}.
|
|
504
|
+
'''
|
|
505
|
+
# from GeodSolve --help option -f ... lat1 lon1 azi1 lat2 lon2 azi2 s12 a12 m12 M12 M21 S12
|
|
506
|
+
_Names_ = (_lat1_, _lon1_, _azi1_, _lat2_, _lon2_, _azi2_, _s12_, _a12_, _m12_, _M12_, _M21_, _S12_)
|
|
507
|
+
_Units_ = (_Lat, _Lon, _Azi, _Lat, _Lon, _Azi, _M, _Deg, _Pass, _Pass, _Pass, _M2)
|
|
508
|
+
|
|
509
|
+
|
|
473
510
|
class Inverse10Tuple(_GTuple):
|
|
474
511
|
'''10-Tuple C{(a12, s12, salp1, calp1, salp2, calp2, m12, M12, M21, S12)} with arc length
|
|
475
512
|
C{a12} in C{degrees}, distance C{s12} and reduced length C{m12} in C{meter}, area
|
|
@@ -687,6 +724,16 @@ def _isfinite(x): # mimick geomath.Math.isfinite
|
|
|
687
724
|
return _math_isfinite(x) # and fabs(x) <= _MAX
|
|
688
725
|
|
|
689
726
|
|
|
727
|
+
def _llz2line(line, **llz2):
|
|
728
|
+
'''(INTERNAL) Set C{line.lat2, .lon2, .azi2} from C{llz2}.
|
|
729
|
+
'''
|
|
730
|
+
if llz2:
|
|
731
|
+
llz2 = _xkwds_not(None, **_xkwds_kwds(llz2, lat2=None, lon2=None, azi2=None))
|
|
732
|
+
if llz2:
|
|
733
|
+
line.__dict__.update(llz2)
|
|
734
|
+
return line
|
|
735
|
+
|
|
736
|
+
|
|
690
737
|
def _norm2(x, y): # mimick geomath.Math.norm
|
|
691
738
|
'''Normalize C{B{x}} and C{B{y}}.
|
|
692
739
|
|
pygeodesy/lazily.py
CHANGED
|
@@ -48,26 +48,27 @@ except ImportError as x: # Python 2.6-
|
|
|
48
48
|
from os import getenv as _getenv
|
|
49
49
|
# import sys as _sys # from .interns
|
|
50
50
|
|
|
51
|
-
__as__
|
|
52
|
-
_dunder_all_
|
|
53
|
-
_enabled_
|
|
54
|
-
_FOR_DOCS
|
|
55
|
-
_i0
|
|
56
|
-
_init__all__
|
|
57
|
-
_lazily_
|
|
58
|
-
_lazily_imported_
|
|
59
|
-
_PYGEODESY_GEOCONVERT_
|
|
60
|
-
_PYGEODESY_GEODSOLVE_
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
__as__ = ' as '
|
|
52
|
+
_dunder_all_ = '__all__' # in .__main__
|
|
53
|
+
_enabled_ = 'enabled'
|
|
54
|
+
_FOR_DOCS = _getenv('PYGEODESY_FOR_DOCS', NN) # for epydoc ...
|
|
55
|
+
_i0 = () # PYCHOK empty tuple
|
|
56
|
+
_init__all__ = _FOR_DOCS or _getenv('PYGEODESY_INIT__ALL__', _dunder_all_) == _dunder_all_ # PYCHOK exported
|
|
57
|
+
_lazily_ = 'lazily'
|
|
58
|
+
_lazily_imported_ = _SPACE_(_HASH_, _lazily_, 'imported')
|
|
59
|
+
_PYGEODESY_GEOCONVERT_ = 'PYGEODESY_GEOCONVERT' # PYCHOK .mgrs, test.bases
|
|
60
|
+
_PYGEODESY_GEODSOLVE_ = 'PYGEODESY_GEODSOLVE' # PYCHOK .geodsolve, test.bases
|
|
61
|
+
_PYGEODESY_INTERSECTTOOL_ = 'PYGEODESY_INTERSECTTOOL' # PYCHOK .intersectool, test.bases
|
|
62
|
+
_PYGEODESY_LAZY_IMPORT_ = 'PYGEODESY_LAZY_IMPORT'
|
|
63
|
+
_PYGEODESY_RHUMBSOLVE_ = 'PYGEODESY_RHUMBSOLVE' # PYCHOK .rhumb.solve, test.bases
|
|
64
|
+
_PYTHON_X_DEV = getattr(_sys, '_xoptions', {}).get('dev', # Python 3.2+
|
|
64
65
|
_getenv('PYTHONDEVMODE', NN)) # PYCHOK exported
|
|
65
|
-
_sys_version_info2
|
|
66
|
-
_unlazy = _unLazy0
|
|
67
|
-
_WARNINGS_X_DEV
|
|
68
|
-
|
|
66
|
+
_sys_version_info2 = _sys.version_info[:2] # in .basics, .fmath, ...
|
|
67
|
+
_unlazy = _unLazy0 = _isfrozen or _sys_version_info2 < (3, 7) # PYCHOK mod.__getattr__ 3.7+
|
|
68
|
+
_WARNINGS_X_DEV = _getenv('PYGEODESY_WARNINGS', NN) and (
|
|
69
|
+
_PYTHON_X_DEV or bool(_sys.warnoptions)) # PYCHOK .props
|
|
69
70
|
# @module_property[_RO?] <https://GitHub.com/jtushman/proxy_tools/>
|
|
70
|
-
isLazy
|
|
71
|
+
isLazy = None # see @var isLazy in .__init__
|
|
71
72
|
|
|
72
73
|
|
|
73
74
|
class LazyAttributeError(AttributeError):
|
|
@@ -283,7 +284,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
283
284
|
fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
|
|
284
285
|
'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
|
|
285
286
|
gars=_i('Garef', 'GARSError'),
|
|
286
|
-
geodesici=_i('
|
|
287
|
+
geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Middle5Tuple',
|
|
288
|
+
'Intersector', 'Intersector5Tuple', 'XDict'),
|
|
287
289
|
geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
|
|
288
290
|
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
289
291
|
'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
|
|
@@ -409,7 +411,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
409
411
|
'HeightIDW', 'HeightIDW2', 'HeightIDW3', 'Helmert7Tuple',
|
|
410
412
|
'Lam_', 'LatLonExact4Tuple', 'NearestOn4Tuple', 'Ned3Tuple',
|
|
411
413
|
'Phi_', 'RefFrameError', 'Rhumb7Tuple', 'RhumbOrder2Tuple',
|
|
412
|
-
'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple'),
|
|
414
|
+
'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple', 'XDist'),
|
|
413
415
|
deprecated_consterns=_i('EPS1_2', 'MANTIS', 'OK'),
|
|
414
416
|
deprecated_datum=_i('Curvature2Tuple', 'Datum', 'Ellipsoid', 'Transform', # assert
|
|
415
417
|
'Datums', 'Ellipsoids', 'Transforms',
|
|
@@ -519,7 +521,7 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
519
521
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
520
522
|
|
|
521
523
|
__all__ = _ALL_LAZY.lazily
|
|
522
|
-
__version__ = '24.
|
|
524
|
+
__version__ = '24.07.09'
|
|
523
525
|
|
|
524
526
|
|
|
525
527
|
def _ALL_OTHER(*objs):
|
pygeodesy/ltpTuples.py
CHANGED
|
@@ -36,7 +36,7 @@ from pygeodesy.vector3d import Vector3d
|
|
|
36
36
|
# from math import cos, radians # from .utily
|
|
37
37
|
|
|
38
38
|
__all__ = _ALL_LAZY.ltpTuples
|
|
39
|
-
__version__ = '24.06.
|
|
39
|
+
__version__ = '24.06.28'
|
|
40
40
|
|
|
41
41
|
_aer_ = 'aer'
|
|
42
42
|
_alt_ = 'alt'
|
|
@@ -349,7 +349,7 @@ class Aer(_AbcBase):
|
|
|
349
349
|
number of (decimal) digits, unstripped
|
|
350
350
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
351
351
|
backets format (C{str}) and separator
|
|
352
|
-
C{B{sep}=
|
|
352
|
+
C{B{sep}=", "} to join (C{str}).
|
|
353
353
|
|
|
354
354
|
@return: This AER as "[degrees360, degrees90, meter]" (C{str}).
|
|
355
355
|
'''
|
|
@@ -572,7 +572,7 @@ class Ned(_AbcBase):
|
|
|
572
572
|
number of (decimal) digits, unstripped
|
|
573
573
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
574
574
|
backets format (C{str}) and separator
|
|
575
|
-
C{B{sep}=
|
|
575
|
+
C{B{sep}=", "} to join (C{str}).
|
|
576
576
|
|
|
577
577
|
@return: This NED as "[meter, meter, meter]" (C{str}).
|
|
578
578
|
'''
|
|
@@ -659,7 +659,7 @@ class _Vector3d(Vector3d):
|
|
|
659
659
|
number of (decimal) digits, unstripped
|
|
660
660
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
661
661
|
backets format (C{str}) and separator
|
|
662
|
-
C{B{sep}=
|
|
662
|
+
C{B{sep}=", "} to join (C{str}).
|
|
663
663
|
|
|
664
664
|
@return: This XYZ as "[meter, meter, meter]" (C{str}).
|
|
665
665
|
'''
|