pygeodesy 24.7.7__py2.py3-none-any.whl → 24.8.4__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.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/METADATA +28 -26
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/RECORD +39 -39
- pygeodesy/__init__.py +50 -51
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/cartesianBase.py +6 -7
- pygeodesy/css.py +5 -5
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +12 -6
- pygeodesy/gars.py +59 -52
- pygeodesy/geodesici.py +232 -137
- pygeodesy/geodesicw.py +70 -45
- pygeodesy/geodesicx/gx.py +8 -8
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +12 -3
- pygeodesy/geohash.py +484 -267
- pygeodesy/geoids.py +13 -11
- pygeodesy/heights.py +30 -40
- pygeodesy/internals.py +19 -6
- pygeodesy/karney.py +85 -79
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +5 -6
- pygeodesy/lazily.py +21 -19
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +6 -6
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +26 -12
- pygeodesy/triaxials.py +6 -7
- pygeodesy/units.py +34 -17
- pygeodesy/wgrs.py +93 -83
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/top_level.txt +0 -0
pygeodesy/geoids.py
CHANGED
|
@@ -93,15 +93,14 @@ from pygeodesy.fmath import favg, Fdot, fdot, Fhorner, frange
|
|
|
93
93
|
from pygeodesy.heights import _as_llis2, _ascalar, _height_called, HeightError, \
|
|
94
94
|
_HeightsBase, _ellipsoidal_datum, _Wrap
|
|
95
95
|
# from pygeodesy.internals import _version2 # _MODS
|
|
96
|
-
from pygeodesy.interns import MISSING, NN, _4_, _COLONSPACE_, _COMMASPACE_, \
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
_stdev_, _tbd_, _W_, _width_
|
|
96
|
+
from pygeodesy.interns import MISSING, NN, _4_, _COLONSPACE_, _COMMASPACE_, _cubic_, \
|
|
97
|
+
_E_, _height_, _in_, _kind_, _lat_, _linear_, _lon_, \
|
|
98
|
+
_mean_, _N_, _n_a_, _numpy_, _on_, _outside_, _S_, _s_, \
|
|
99
|
+
_scipy_, _SPACE_, _stdev_, _tbd_, _W_, _width_
|
|
101
100
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
|
|
102
101
|
from pygeodesy.named import _name__, _Named, _NamedTuple
|
|
103
102
|
# from pygeodesy.namedTuples import LatLon3Tuple # _MODS
|
|
104
|
-
from pygeodesy.props import deprecated_method, Property_RO, property_RO
|
|
103
|
+
from pygeodesy.props import deprecated_method, Property_RO, property_RO, property_ROver
|
|
105
104
|
from pygeodesy.streprs import attrs, Fmt, fstr, pairs
|
|
106
105
|
from pygeodesy.units import Height, Int_, Lat, Lon
|
|
107
106
|
# from pygeodesy.utily import _Wrap # from .heights
|
|
@@ -118,7 +117,7 @@ except ImportError: # Python 3+
|
|
|
118
117
|
from io import BytesIO as _BytesIO # PYCHOK expected
|
|
119
118
|
|
|
120
119
|
__all__ = _ALL_LAZY.geoids
|
|
121
|
-
__version__ = '24.
|
|
120
|
+
__version__ = '24.07.25'
|
|
122
121
|
|
|
123
122
|
_assert_ = 'assert'
|
|
124
123
|
_bHASH_ = b'#'
|
|
@@ -288,7 +287,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
288
287
|
|
|
289
288
|
def _called(self, llis, scipy, wrap=False, H=False):
|
|
290
289
|
# handle __call__
|
|
291
|
-
_H =
|
|
290
|
+
_H = self._heightOrthometric if H else None
|
|
292
291
|
_as, llis = _as_llis2(llis, Error=GeoidError)
|
|
293
292
|
hs, _w = [], _Wrap._latlonop(wrap)
|
|
294
293
|
_a, _h = hs.append, self._hGeoid
|
|
@@ -417,6 +416,10 @@ class _GeoidBase(_HeightsBase):
|
|
|
417
416
|
'''
|
|
418
417
|
return _height_called(self, lats, lons, Error=GeoidError, **wrap)
|
|
419
418
|
|
|
419
|
+
@property_ROver
|
|
420
|
+
def _heightOrthometric(self):
|
|
421
|
+
return _MODS.formy.heightOrthometric # overwrite property_ROver
|
|
422
|
+
|
|
420
423
|
def _hGeoid(self, lat, lon):
|
|
421
424
|
out = self.outside(lat, lon)
|
|
422
425
|
if out:
|
|
@@ -473,12 +476,11 @@ class _GeoidBase(_HeightsBase):
|
|
|
473
476
|
'''(INTERNAL) I{Must be overloaded}.'''
|
|
474
477
|
self._notOverloaded(lat, lon)
|
|
475
478
|
|
|
476
|
-
@
|
|
479
|
+
@property_ROver
|
|
477
480
|
def _LL3T(self):
|
|
478
481
|
'''(INTERNAL) Get L{LatLon3Tuple}, I{once}.
|
|
479
482
|
'''
|
|
480
|
-
|
|
481
|
-
return T
|
|
483
|
+
return _MODS.namedTuples.LatLon3Tuple # overwrite property_ROver
|
|
482
484
|
|
|
483
485
|
def _llh3(self, lat, lon):
|
|
484
486
|
return self._LL3T(lat, lon, self._hGeoid(lat, lon), name=self.name)
|
pygeodesy/heights.py
CHANGED
|
@@ -69,7 +69,7 @@ C{>>> hs = hinterpolator.height(lats, lons)}
|
|
|
69
69
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
70
70
|
|
|
71
71
|
from pygeodesy.basics import isscalar, len2, map1, map2, _xnumpy, _xscipy
|
|
72
|
-
from pygeodesy.constants import EPS, PI, PI2, _0_0, _90_0, _180_0
|
|
72
|
+
from pygeodesy.constants import EPS, PI, PI_2, PI2, _0_0, _90_0, _180_0
|
|
73
73
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
74
74
|
from pygeodesy.errors import _AssertionError, LenError, PointsError, \
|
|
75
75
|
_SciPyIssue, _xattr, _xkwds, _xkwds_get, _xkwds_item2
|
|
@@ -83,7 +83,7 @@ from pygeodesy.interns import NN, _COMMASPACE_, _cubic_, _insufficient_, _linear
|
|
|
83
83
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _FOR_DOCS
|
|
84
84
|
from pygeodesy.named import _name2__, _Named
|
|
85
85
|
from pygeodesy.points import _distanceTo, LatLon_, Fmt, radians, _Wrap
|
|
86
|
-
from pygeodesy.props import Property_RO, property_RO
|
|
86
|
+
from pygeodesy.props import Property_RO, property_RO, property_ROver
|
|
87
87
|
# from pygeodesy.streprs import Fmt # from .points
|
|
88
88
|
from pygeodesy.units import _isDegrees, Float_, Int_
|
|
89
89
|
# from pygeodesy.utily import _Wrap # from .points
|
|
@@ -91,7 +91,7 @@ from pygeodesy.units import _isDegrees, Float_, Int_
|
|
|
91
91
|
# from math import radians # from .points
|
|
92
92
|
|
|
93
93
|
__all__ = _ALL_LAZY.heights
|
|
94
|
-
__version__ = '24.
|
|
94
|
+
__version__ = '24.07.25'
|
|
95
95
|
|
|
96
96
|
_error_ = 'error'
|
|
97
97
|
_formy = _MODS.into(formy=__name__)
|
|
@@ -169,14 +169,13 @@ def _insufficientError(need, Error=HeightError, **name_value): # PYCHOK no cove
|
|
|
169
169
|
return Error(txt=t, **name_value)
|
|
170
170
|
|
|
171
171
|
|
|
172
|
-
def
|
|
172
|
+
def _orderedup(ts, lo=EPS, hi=PI2-EPS):
|
|
173
173
|
# clip, order and remove duplicates
|
|
174
|
-
# p
|
|
174
|
+
# p = 0
|
|
175
175
|
# for k in sorted(max(lo, min(hi, t)) for t in ts):
|
|
176
176
|
# if k > p:
|
|
177
|
-
#
|
|
177
|
+
# yield k
|
|
178
178
|
# p = k
|
|
179
|
-
# return ks
|
|
180
179
|
return sorted(set(max(lo, min(hi, t)) for t in ts)) # list
|
|
181
180
|
|
|
182
181
|
|
|
@@ -227,8 +226,6 @@ class _HeightBase(_Named): # in .geoids
|
|
|
227
226
|
class _HeightsBase(_HeightBase): # in .geoids
|
|
228
227
|
'''(INTERNAL) Interpolator base class.
|
|
229
228
|
'''
|
|
230
|
-
_np_sp = None # (numpy, scipy)
|
|
231
|
-
|
|
232
229
|
def __call__(self, *llis, **wrap): # PYCHOK no cover
|
|
233
230
|
'''Interpolate the height for one or several locations. I{Must be overloaded}.
|
|
234
231
|
|
|
@@ -290,46 +287,37 @@ class _HeightsBase(_HeightBase): # in .geoids
|
|
|
290
287
|
'''
|
|
291
288
|
self._notOverloaded(lats, lons, **wrap)
|
|
292
289
|
|
|
293
|
-
def _np_sp2(self, throwarnings=False):
|
|
290
|
+
def _np_sp2(self, throwarnings=False): # PYCHOK no cover
|
|
294
291
|
'''(INTERNAL) Import C{numpy} and C{scipy}, once.
|
|
295
292
|
'''
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if
|
|
301
|
-
import
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
sp = _xscipy(self.__class__, 1, 2)
|
|
307
|
-
np = _xnumpy(self.__class__, 1, 9)
|
|
308
|
-
|
|
309
|
-
_HeightsBase._np_sp = t = np, sp
|
|
310
|
-
return t
|
|
311
|
-
|
|
312
|
-
@Property_RO
|
|
293
|
+
# raise SciPyWarnings, but not if
|
|
294
|
+
# scipy has already been imported
|
|
295
|
+
if throwarnings: # PYCHOK no cover
|
|
296
|
+
import sys
|
|
297
|
+
if _scipy_ not in sys.modules:
|
|
298
|
+
import warnings
|
|
299
|
+
warnings.filterwarnings(_error_)
|
|
300
|
+
return self.numpy, self.scipy
|
|
301
|
+
|
|
302
|
+
@property_ROver
|
|
313
303
|
def numpy(self):
|
|
314
304
|
'''Get the C{numpy} module or C{None}.
|
|
315
305
|
'''
|
|
316
|
-
|
|
317
|
-
return np
|
|
306
|
+
return _xnumpy(self.__class__, 1, 9) # overwrite property_ROver
|
|
318
307
|
|
|
319
|
-
@
|
|
308
|
+
@property_ROver
|
|
320
309
|
def scipy(self):
|
|
321
310
|
'''Get the C{scipy} module or C{None}.
|
|
322
311
|
'''
|
|
323
|
-
|
|
324
|
-
return sp
|
|
312
|
+
return _xscipy(self.__class__, 1, 2) # overwrite property_ROver
|
|
325
313
|
|
|
326
|
-
@
|
|
314
|
+
@property_ROver
|
|
327
315
|
def scipy_interpolate(self):
|
|
328
316
|
'''Get the C{scipy.interpolate} module or C{None}.
|
|
329
317
|
'''
|
|
330
318
|
_ = self.scipy
|
|
331
319
|
import scipy.interpolate as spi # scipy 1.2.2
|
|
332
|
-
return spi
|
|
320
|
+
return spi # overwrite property_ROver
|
|
333
321
|
|
|
334
322
|
def _scipy_version(self, **n):
|
|
335
323
|
'''Get the C{scipy} version as 2- or 3-tuple C{(major, minor, micro)}.
|
|
@@ -441,19 +429,20 @@ class HeightLSQBiSpline(_HeightsBase):
|
|
|
441
429
|
'''
|
|
442
430
|
_kmin = 16 # k = 3, always
|
|
443
431
|
|
|
444
|
-
def __init__(self, knots, weight=None, **name_wrap):
|
|
432
|
+
def __init__(self, knots, weight=None, low=1e-4, **name_wrap):
|
|
445
433
|
'''New L{HeightLSQBiSpline} interpolator.
|
|
446
434
|
|
|
447
435
|
@arg knots: The points with known height (C{LatLon}s).
|
|
448
436
|
@kwarg weight: Optional weight or weights for each B{C{knot}}
|
|
449
437
|
(C{scalar} or C{scalar}s).
|
|
438
|
+
@kwarg low: Optional lower bound for I{ordered knots} (C{radians}).
|
|
450
439
|
@kwarg name_wrap: Optional C{B{name}=NN} for this height interpolator
|
|
451
440
|
(C{str}) and keyword argument C{b{wrap}=False} to wrap or
|
|
452
441
|
I{normalize} all B{C{knots}} and B{C{llis}} locations iff
|
|
453
442
|
C{True} (C{bool}).
|
|
454
443
|
|
|
455
|
-
@raise HeightError: Insufficient number of B{C{knots}} or
|
|
456
|
-
|
|
444
|
+
@raise HeightError: Insufficient number of B{C{knots}} or an invalid
|
|
445
|
+
B{C{knot}}, B{C{weight}} or B{C{eps}}.
|
|
457
446
|
|
|
458
447
|
@raise LenError: Unequal number of B{C{knots}} and B{C{weight}}s.
|
|
459
448
|
|
|
@@ -487,9 +476,10 @@ class HeightLSQBiSpline(_HeightsBase):
|
|
|
487
476
|
w = Fmt.INDEX(weight=w.index(m))
|
|
488
477
|
raise HeightError(w, m)
|
|
489
478
|
try:
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
479
|
+
if not EPS < low < (PI_2 - EPS): # 1e-4 like SciPy example
|
|
480
|
+
raise HeightError(low=low)
|
|
481
|
+
ps = np.array(_orderedup(xs, low, PI2 - low))
|
|
482
|
+
ts = np.array(_orderedup(ys, low, PI - low))
|
|
493
483
|
self._ev = spi.LSQSphereBivariateSpline(ys, xs, hs,
|
|
494
484
|
ts, ps, eps=EPS, w=w).ev
|
|
495
485
|
except Exception as x:
|
pygeodesy/internals.py
CHANGED
|
@@ -213,6 +213,13 @@ class _MODS_Base(object):
|
|
|
213
213
|
from pygeodesy import streprs # DON'T _lazy_import2
|
|
214
214
|
return streprs
|
|
215
215
|
|
|
216
|
+
@_Property_RO
|
|
217
|
+
def version(self):
|
|
218
|
+
'''Get pygeodesy version, I{once}.
|
|
219
|
+
'''
|
|
220
|
+
from pygeodesy import version
|
|
221
|
+
return version
|
|
222
|
+
|
|
216
223
|
_MODS = _MODS_Base() # PYCHOK overwritten by .lazily
|
|
217
224
|
|
|
218
225
|
|
|
@@ -430,7 +437,7 @@ def _print7(nl=0, nt=0, prec=6, prefix=NN, sep=_SPACE_, file=_sys.stdout,
|
|
|
430
437
|
|
|
431
438
|
|
|
432
439
|
def _Pythonarchine(sep=NN): # in .lazily, test/bases.py versions
|
|
433
|
-
'''(INTERNAL) Get PyPy and Python versions,
|
|
440
|
+
'''(INTERNAL) Get PyPy and Python versions, bits and machine as C{3- or 4-list} or C{str}.
|
|
434
441
|
'''
|
|
435
442
|
l3 = _MODS.Pythonarchine
|
|
436
443
|
return sep.join(l3) if sep else l3 # 3- or 4-list
|
|
@@ -576,16 +583,22 @@ def _version_ints(vs):
|
|
|
576
583
|
return tuple(_ints(vs))
|
|
577
584
|
|
|
578
585
|
|
|
586
|
+
def _versions(sep=_SPACE_):
|
|
587
|
+
'''(INTERNAL) Get pygeodesy, PyPy and Python versions, bits, machine and OS as C{7- or 8-list} or C{str}.
|
|
588
|
+
'''
|
|
589
|
+
l7 = [_pygeodesy_, _MODS.version] + _Pythonarchine() + _osversion2()
|
|
590
|
+
return sep.join(l7) if sep else l7 # 5- or 6-list
|
|
591
|
+
|
|
592
|
+
|
|
579
593
|
__all__ = tuple(map(_dunder_nameof, (machine, print_, printf)))
|
|
580
|
-
__version__ = '24.
|
|
594
|
+
__version__ = '24.08.01'
|
|
581
595
|
|
|
582
596
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
583
597
|
|
|
584
|
-
from pygeodesy import _isfrozen, isLazy
|
|
598
|
+
from pygeodesy import _isfrozen, isLazy
|
|
585
599
|
|
|
586
|
-
print_(
|
|
587
|
-
|
|
588
|
-
'isLazy', isLazy]))
|
|
600
|
+
print_(*(_versions(sep=NN) + ['_isfrozen', _isfrozen,
|
|
601
|
+
'isLazy', isLazy]))
|
|
589
602
|
|
|
590
603
|
# **) MIT License
|
|
591
604
|
#
|
pygeodesy/karney.py
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
u'''Wrapper around several C{geomath.Math} functions from I{Karney}'s Python package U{geographiclib
|
|
5
5
|
<https://PyPI.org/project/geographiclib>}, provided that package is installed.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
either by C{key} or by C{attribute} name.
|
|
9
|
-
All methods of the I{wrapped} L{Geodesic<geodesicw.Geodesic>} and L{GeodesicLine<geodesicw.GeodesicLine>}
|
|
7
|
+
Methods of the I{wrapped} L{Geodesic<geodesicw.Geodesic>} and L{GeodesicLine<geodesicw.GeodesicLine>}
|
|
10
8
|
classes return a L{GDict} instance offering access to the C{dict} items either by C{key} or by
|
|
11
9
|
C{attribute} name.
|
|
12
10
|
|
|
13
|
-
With env variable C{PYGEODESY_GEOGRAPHICLIB} left undefined or set to C{"2"}, modules L{
|
|
14
|
-
L{
|
|
11
|
+
With env variable C{PYGEODESY_GEOGRAPHICLIB} left undefined or set to C{"2"}, modules L{geodesicw},
|
|
12
|
+
L{geodesicx} and this module will use U{GeographicLib 2.0+<https://GeographicLib.SourceForge.io/C++/doc/>}
|
|
15
13
|
and newer transcoding, otherwise C{1.52} or older.
|
|
16
14
|
|
|
17
15
|
Karney-based functionality
|
|
@@ -60,8 +58,11 @@ Karney-based functionality
|
|
|
60
58
|
- L{GnomonicExact}, L{GnomonicGeodSolve}, L{GnomonicKarney} -- U{Gnomonic
|
|
61
59
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Gnomonic.html>}
|
|
62
60
|
|
|
61
|
+
- L{Intersector} -- U{Intersect
|
|
62
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Intersect.html>} from I{GeographicLib 2.3+}
|
|
63
|
+
|
|
63
64
|
- L{JacobiConformal} -- U{JacobiConformal
|
|
64
|
-
<https://
|
|
65
|
+
<https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1experimental_1_1JacobiConformal.html>}
|
|
65
66
|
|
|
66
67
|
- L{KTransverseMercator} - U{TransverseMercator
|
|
67
68
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1TransverseMercator.html>}
|
|
@@ -94,13 +95,14 @@ are I{transcoded} from C++ classes in I{Karney}'s U{GeographicLib<https://Geogra
|
|
|
94
95
|
|
|
95
96
|
2. These C{pygeodesy} modules and classes
|
|
96
97
|
|
|
97
|
-
- L{ellipsoidalGeodSolve}, L{ellipsoidalKarney}, L{geodsolve}, L{karney}, L{rhumb.solve}
|
|
98
|
+
- L{ellipsoidalGeodSolve}, L{ellipsoidalKarney}, L{geodesici}, L{geodsolve}, L{karney}, L{rhumb.solve}
|
|
98
99
|
- L{EquidistantKarney}, L{FrechetKarney}, L{GeodesicSolve}, L{GeodesicLineSolve}, L{GnomonicGeodSolve},
|
|
99
|
-
L{GnomonicKarney}, L{HeightIDWkarney}
|
|
100
|
+
L{GnomonicKarney}, L{HeightIDWkarney}, L{Intersectool}
|
|
100
101
|
|
|
101
|
-
are or use I{wrappers} around I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>}
|
|
102
|
-
C
|
|
103
|
-
|
|
102
|
+
are or use I{wrappers} around I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>} or
|
|
103
|
+
C++ utility U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>},
|
|
104
|
+
U{IntersectTool<https://GeographicLib.SourceForge.io/C++/doc/IntersectTool.1.html>} or
|
|
105
|
+
U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}.
|
|
104
106
|
|
|
105
107
|
3. All C{pygeodesy} functions and methods to compute I{ellipsoidal} intersections, nearest points and trilaterations
|
|
106
108
|
|
|
@@ -139,12 +141,11 @@ in C{pygeodesy} are based on I{Karney}'s post U{Area of a spherical polygon
|
|
|
139
141
|
# make sure int/int division yields float quotient, see .basics
|
|
140
142
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
141
143
|
|
|
142
|
-
from pygeodesy.basics import _copysign,
|
|
143
|
-
|
|
144
|
+
from pygeodesy.basics import _copysign, isint, neg, unsigned0, _xgeographiclib, \
|
|
145
|
+
_zip, _version_info
|
|
144
146
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
|
|
145
147
|
_1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
146
|
-
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
|
|
147
|
-
_xkwds_kwds, _xkwds_not
|
|
148
|
+
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
|
|
148
149
|
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
149
150
|
# from pygeodesy.internals import _version_info # from .basics
|
|
150
151
|
from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
@@ -153,15 +154,15 @@ from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
|
153
154
|
_UNDER_, _X_, _BAR_ # PYCHOK used!
|
|
154
155
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
155
156
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
156
|
-
from pygeodesy.props import deprecated_method, Property_RO
|
|
157
|
-
from pygeodesy.units import
|
|
157
|
+
from pygeodesy.props import deprecated_method, Property_RO, property_ROnce
|
|
158
|
+
from pygeodesy.units import Azimuth as _Azi, Degrees as _Deg, Lat, Lon, \
|
|
158
159
|
Meter as _M, Meter2 as _M2, Number_
|
|
159
160
|
from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
160
161
|
|
|
161
162
|
# from math import fabs # from .utily
|
|
162
163
|
|
|
163
164
|
__all__ = _ALL_LAZY.karney
|
|
164
|
-
__version__ = '24.07.
|
|
165
|
+
__version__ = '24.07.25'
|
|
165
166
|
|
|
166
167
|
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
|
|
167
168
|
_perimeter_ = 'perimeter'
|
|
@@ -208,39 +209,39 @@ class Area3Tuple(_NamedTuple): # in .geodesicx.gxarea
|
|
|
208
209
|
_Units_ = ( Number_, _M, _M2)
|
|
209
210
|
|
|
210
211
|
|
|
211
|
-
class Caps(object):
|
|
212
|
+
class Caps(object):
|
|
212
213
|
'''(INTERNAL) Overriden by C{Caps} below.
|
|
213
214
|
'''
|
|
214
|
-
EMPTY
|
|
215
|
-
_CAP_1
|
|
216
|
-
_CAP_1p
|
|
217
|
-
_CAP_2
|
|
218
|
-
_CAP_3
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
# _CAP_MASK
|
|
222
|
-
LATITUDE
|
|
223
|
-
LONGITUDE
|
|
224
|
-
AZIMUTH
|
|
225
|
-
DISTANCE
|
|
226
|
-
DISTANCE_IN
|
|
227
|
-
REDUCEDLENGTH
|
|
228
|
-
GEODESICSCALE
|
|
229
|
-
AREA
|
|
230
|
-
|
|
231
|
-
STANDARD
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
LINE_OFF
|
|
242
|
-
|
|
243
|
-
|
|
215
|
+
EMPTY = 0 # formerly aka NONE
|
|
216
|
+
_CAP_1 = 1 << 0 # for goedesici/-w
|
|
217
|
+
_CAP_1p = 1 << 1 # for goedesici/-w
|
|
218
|
+
_CAP_2 = 1 << 2
|
|
219
|
+
_CAP_3 = 1 << 3 # for goedesici/-w
|
|
220
|
+
_CAP_4 = 1 << 4 # for goedesicw
|
|
221
|
+
_CAP_ALL = 0x1F
|
|
222
|
+
# _CAP_MASK = _CAP_ALL
|
|
223
|
+
LATITUDE = 1 << 7 # compute latitude C{lat2}
|
|
224
|
+
LONGITUDE = 1 << 8 | _CAP_3 # compute longitude C{lon2}
|
|
225
|
+
AZIMUTH = 1 << 9 # azimuths C{azi1} and C{azi2}
|
|
226
|
+
DISTANCE = 1 << 10 | _CAP_1 # compute distance C{s12}
|
|
227
|
+
DISTANCE_IN = 1 << 11 | _CAP_1 | _CAP_1p # allow distance C{s12} in Direct
|
|
228
|
+
REDUCEDLENGTH = 1 << 12 | _CAP_1 | _CAP_2 # compute reduced length C{m12}
|
|
229
|
+
GEODESICSCALE = 1 << 13 | _CAP_1 | _CAP_2 # compute geodesic scales C{M12} and C{M21}
|
|
230
|
+
AREA = 1 << 14 | _CAP_4 # compute area C{S12}
|
|
231
|
+
|
|
232
|
+
STANDARD = AZIMUTH | DISTANCE | LATITUDE | LONGITUDE
|
|
233
|
+
|
|
234
|
+
_DIRECT3 = AZIMUTH | LATITUDE | LONGITUDE # for goedesicw only
|
|
235
|
+
_INVERSE3 = AZIMUTH | DISTANCE # for goedesicw only
|
|
236
|
+
_STD = STANDARD # for goedesicw only
|
|
237
|
+
_STD_LINE = _STD | DISTANCE_IN # for goedesici/-w
|
|
238
|
+
|
|
239
|
+
LINE_CAPS = _STD_LINE | REDUCEDLENGTH | GEODESICSCALE # .geodesici only
|
|
240
|
+
LONG_UNROLL = 1 << 15 # unroll C{lon2} in .Direct and .Position
|
|
241
|
+
# = 1 << 16 # unused
|
|
242
|
+
LINE_OFF = 1 << 17 # Line without updates from parent geodesic or rhumb
|
|
243
|
+
REVERSE2 = 1 << 18 # reverse C{azi2}
|
|
244
|
+
ALL = 0x7F80 | _CAP_ALL # without LONG_UNROLL, LINE_OFF, REVERSE2 and _DEBUG_*
|
|
244
245
|
|
|
245
246
|
LATITUDE_LONGITUDE = LATITUDE | LONGITUDE
|
|
246
247
|
LATITUDE_LONGITUDE_AREA = LATITUDE | LONGITUDE | AREA
|
|
@@ -248,35 +249,38 @@ class Caps(object): # PYCHOK
|
|
|
248
249
|
AZIMUTH_DISTANCE = AZIMUTH | DISTANCE
|
|
249
250
|
AZIMUTH_DISTANCE_AREA = AZIMUTH | DISTANCE | AREA
|
|
250
251
|
|
|
251
|
-
|
|
252
|
-
_S_CALPs_ = 1 << 19 # (INTERNAL) GeodesicExact._GenInverse
|
|
252
|
+
_SALP_CALPs_ = 1 << 19 # (INTERNAL) GeodesicExact._GenInverse
|
|
253
253
|
|
|
254
254
|
_DEBUG_AREA = 1 << 20 # (INTERNAL) include Line details
|
|
255
255
|
_DEBUG_DIRECT = 1 << 21 # (INTERNAL) include Direct details
|
|
256
256
|
_DEBUG_INVERSE = 1 << 22 # (INTERNAL) include Inverse details
|
|
257
257
|
_DEBUG_LINE = 1 << 23 # (INTERNAL) include Line details
|
|
258
258
|
_DEBUG_ALL = _DEBUG_AREA | _DEBUG_DIRECT | _DEBUG_INVERSE | \
|
|
259
|
-
_DEBUG_LINE |
|
|
259
|
+
_DEBUG_LINE | _SALP_CALPs_
|
|
260
260
|
|
|
261
|
-
_OUT_ALL = ALL
|
|
261
|
+
_OUT_ALL = ALL # see geographiclib.geodesiccapabilities.py
|
|
262
262
|
_OUT_MASK = ALL | LONG_UNROLL | REVERSE2 | _DEBUG_ALL
|
|
263
263
|
|
|
264
264
|
_AZIMUTH_LATITUDE_LONGITUDE = AZIMUTH | LATITUDE | LONGITUDE
|
|
265
|
+
_AZIMUTH_LATITUDE_LONG_UNROLL = AZIMUTH | LATITUDE | LONG_UNROLL
|
|
265
266
|
_DEBUG_DIRECT_LINE = _DEBUG_DIRECT | _DEBUG_LINE
|
|
266
267
|
# _DISTANCE_IN_OUT = DISTANCE_IN & _OUT_MASK # == DISTANCE_IN in .gx, .gxline
|
|
267
|
-
_LINE = AZIMUTH | LATITUDE | LONG_UNROLL
|
|
268
268
|
_REDUCEDLENGTH_GEODESICSCALE = REDUCEDLENGTH | GEODESICSCALE
|
|
269
269
|
# _REDUCEDLENGTH_GEODESICSCALE_DISTANCE = REDUCEDLENGTH | GEODESICSCALE | DISTANCE
|
|
270
270
|
|
|
271
|
-
def
|
|
272
|
-
'''
|
|
271
|
+
def items(self):
|
|
272
|
+
'''Yield all I{public} C{Caps} as 2-tuple C{(NAME, mask)}.
|
|
273
|
+
'''
|
|
274
|
+
for n, C in Caps.__class__.__dict__.items():
|
|
275
|
+
if isint(C) and not n.startswith(_UNDER_) \
|
|
276
|
+
and n.replace(_UNDER_, NN).isupper():
|
|
277
|
+
yield n, C
|
|
278
|
+
|
|
279
|
+
def toStr(self, Cask, sep=_BAR_):
|
|
280
|
+
'''Return C{Caps} or an C{outmask} as C{str} or tuple of C{str}s.
|
|
273
281
|
'''
|
|
274
|
-
s =
|
|
275
|
-
|
|
276
|
-
if isint(C) and (Csk & C) and int1s(C) == 1 \
|
|
277
|
-
and (C in (Caps.REVERSE2, Caps._S_CALPs_)
|
|
278
|
-
or c.replace(_UNDER_, NN).isupper()):
|
|
279
|
-
s.append(c)
|
|
282
|
+
s = (n for n, C in sorted(Caps.items())
|
|
283
|
+
if C and (Cask & C) == C) # and int1s(C) <= 3
|
|
280
284
|
return sep.join(s) if sep else tuple(s)
|
|
281
285
|
|
|
282
286
|
Caps = Caps() # PYCHOK singleton
|
|
@@ -287,7 +291,7 @@ C{AREA} - compute area C{S12},
|
|
|
287
291
|
|
|
288
292
|
C{AZIMUTH} - include azimuths C{azi1} and C{azi2},
|
|
289
293
|
|
|
290
|
-
C{DISTANCE} - compute distance C{s12},
|
|
294
|
+
C{DISTANCE} - compute distance C{s12} and angular distance C{a12},
|
|
291
295
|
|
|
292
296
|
C{DISTANCE_IN} - allow distance C{s12} in C{.Direct},
|
|
293
297
|
|
|
@@ -311,7 +315,8 @@ and C{ALL} - all of the above.
|
|
|
311
315
|
|
|
312
316
|
C{STANDARD} = C{AZIMUTH | DISTANCE | DISTANCE_IN | LATITUDE | LONGITUDE}'''
|
|
313
317
|
|
|
314
|
-
|
|
318
|
+
_key2Caps = dict(a12 =Caps.DISTANCE, # in GDict._unCaps
|
|
319
|
+
azi2=Caps.AZIMUTH,
|
|
315
320
|
lat2=Caps.LATITUDE,
|
|
316
321
|
lon2=Caps.LONGITUDE,
|
|
317
322
|
m12 =Caps.REDUCEDLENGTH,
|
|
@@ -322,7 +327,7 @@ _KEY2Caps = dict(azi2=Caps.AZIMUTH, # see GDict._unCaps
|
|
|
322
327
|
|
|
323
328
|
|
|
324
329
|
class _CapsBase(_NamedBase): # in .auxilats, .geodesicx.gxbases
|
|
325
|
-
'''(INTERNAL) Base class for C{
|
|
330
|
+
'''(INTERNAL) Base class for C{Geodesic*}, C{Geodesic*Exact}, C{Intersectool} and C{Rhumb*Base}.
|
|
326
331
|
'''
|
|
327
332
|
ALL = Caps.ALL
|
|
328
333
|
AREA = Caps.AREA
|
|
@@ -473,8 +478,8 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
473
478
|
t = tuple(_g(self, n, dflt) for n in nTuple._Names_)
|
|
474
479
|
return nTuple(t, iteration=self._iteration)
|
|
475
480
|
|
|
476
|
-
def _2X(self, gl, _2X=_X_): # .
|
|
477
|
-
'''(INTERNAL) Rename
|
|
481
|
+
def _2X(self, gl, _2X=_X_): # .Intersectool, .Intersector
|
|
482
|
+
'''(INTERNAL) Rename C{-2} attr to C{-X} or C{-M}.
|
|
478
483
|
'''
|
|
479
484
|
X = GDict(self)
|
|
480
485
|
for n in (_lat2_, _lon2_, _azi2_, _s12_, _a12_):
|
|
@@ -488,8 +493,8 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
488
493
|
def _unCaps(self, outmask): # in .geodsolve
|
|
489
494
|
'''(INTERNAL) Remove superfluous items.
|
|
490
495
|
'''
|
|
491
|
-
for k,
|
|
492
|
-
if k in self and
|
|
496
|
+
for k, C in _key2Caps.items():
|
|
497
|
+
if k in self and (outmask & C) != C:
|
|
493
498
|
self.pop(k) # delattr(self, k)
|
|
494
499
|
return self
|
|
495
500
|
|
|
@@ -531,13 +536,13 @@ class _kWrapped(object): # in .geodesicw
|
|
|
531
536
|
<https://PyPI.org/project/geographiclib>} classes.
|
|
532
537
|
'''
|
|
533
538
|
|
|
534
|
-
@
|
|
539
|
+
@property_ROnce
|
|
535
540
|
def geographiclib(self):
|
|
536
541
|
'''Lazily import C{geographiclib}, provided the U{geographiclib
|
|
537
542
|
<https://PyPI.org/project/geographiclib>} package is installed,
|
|
538
543
|
otherwise raise a C{LazyImportError}.
|
|
539
544
|
'''
|
|
540
|
-
g = _xgeographiclib(self.__class__, 1, 49)
|
|
545
|
+
g = _xgeographiclib(self.__class__.__module__, 1, 49)
|
|
541
546
|
from geographiclib.geodesic import Geodesic
|
|
542
547
|
g.Geodesic = Geodesic
|
|
543
548
|
from geographiclib.geodesicline import GeodesicLine
|
|
@@ -546,7 +551,7 @@ class _kWrapped(object): # in .geodesicw
|
|
|
546
551
|
g.Math = Math
|
|
547
552
|
return g
|
|
548
553
|
|
|
549
|
-
@
|
|
554
|
+
@property_ROnce
|
|
550
555
|
def Math(self):
|
|
551
556
|
'''Wrap the C{geomath.Math} class, provided the U{geographiclib
|
|
552
557
|
<https://PyPI.org/project/geographiclib>} package is installed,
|
|
@@ -599,7 +604,7 @@ class Rhumb8Tuple(_GTuple):
|
|
|
599
604
|
|
|
600
605
|
@kwarg dflt: Default value for missing items (C{any}).
|
|
601
606
|
@kwarg a12_m12_M12_M21_salp1_calp1_salp2_calp2: Optional keyword
|
|
602
|
-
|
|
607
|
+
arguments to specify or override L{Inverse10Tuple} items.
|
|
603
608
|
|
|
604
609
|
@return: L{Inverse10Tuple}C{(a12, s12, salp1, calp1, salp2, calp2,
|
|
605
610
|
m12, M12, M21, S12)}.
|
|
@@ -724,14 +729,15 @@ def _isfinite(x): # mimick geomath.Math.isfinite
|
|
|
724
729
|
return _math_isfinite(x) # and fabs(x) <= _MAX
|
|
725
730
|
|
|
726
731
|
|
|
727
|
-
def
|
|
728
|
-
'''(INTERNAL) Set C{
|
|
732
|
+
def _llz2gl(gl, **llz2): # see .geodesici._llz2G
|
|
733
|
+
'''(INTERNAL) Set C{gl.lat2, .lon2, .azi2} from C{llz2}.
|
|
729
734
|
'''
|
|
730
735
|
if llz2:
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
736
|
+
for n in (_lat2_, _lon2_, _azi2_): # _lat1_, _lon1_, _azi1_
|
|
737
|
+
v = llz2.get(n, None)
|
|
738
|
+
if v is not None:
|
|
739
|
+
setattr(gl, n, v)
|
|
740
|
+
return gl
|
|
735
741
|
|
|
736
742
|
|
|
737
743
|
def _norm2(x, y): # mimick geomath.Math.norm
|
pygeodesy/ktm.py
CHANGED
|
@@ -67,7 +67,7 @@ from cmath import polar
|
|
|
67
67
|
from math import atan2, asinh, cos, cosh, degrees, fabs, sin, sinh, sqrt, tanh
|
|
68
68
|
|
|
69
69
|
__all__ = _ALL_LAZY.ktm
|
|
70
|
-
__version__ = '24.
|
|
70
|
+
__version__ = '24.07.16'
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class KTMError(_ValueError):
|
|
@@ -433,10 +433,7 @@ def _cma(a, b0, b1, Cn):
|
|
|
433
433
|
@see: CPython function U{_Py_c_prod<https://GitHub.com/python/
|
|
434
434
|
cpython/blob/main/Objects/complexobject.c>}.
|
|
435
435
|
|
|
436
|
-
@note: Python function C{cmath.fsum} is no longer available
|
|
437
|
-
but stil mentioned in Note 4 of the comments before
|
|
438
|
-
CPython function U{math_fsum<https://GitHub.com/python/
|
|
439
|
-
cpython/blob/main/Modules/mathmodule.c>}
|
|
436
|
+
@note: Python function C{cmath.fsum} is no longer available.
|
|
440
437
|
'''
|
|
441
438
|
r = fsum1f_(a.real * b0.real, -a.imag * b0.imag, -b1.real, Cn)
|
|
442
439
|
j = fsum1f_(a.real * b0.imag, a.imag * b0.real, -b1.imag)
|
pygeodesy/latlonBase.py
CHANGED
|
@@ -41,7 +41,7 @@ from pygeodesy.namedTuples import Bounds2Tuple, LatLon2Tuple, PhiLam2Tuple, \
|
|
|
41
41
|
Trilaterate5Tuple
|
|
42
42
|
# from pygeodesy.nvectorBase import _N_vector_ # _MODS
|
|
43
43
|
from pygeodesy.props import deprecated_method, Property, Property_RO, \
|
|
44
|
-
property_RO, _update_all
|
|
44
|
+
property_RO, property_ROnce, _update_all
|
|
45
45
|
# from pygeodesy.streprs import Fmt, hstr # from .named, _MODS
|
|
46
46
|
from pygeodesy.units import _isDegrees, _isRadius, Distance_, Lat, Lon, \
|
|
47
47
|
Height, Radius, Radius_, Scalar, Scalar_
|
|
@@ -54,7 +54,7 @@ from contextlib import contextmanager
|
|
|
54
54
|
from math import asin, cos, degrees, fabs, radians
|
|
55
55
|
|
|
56
56
|
__all__ = _ALL_LAZY.latlonBase
|
|
57
|
-
__version__ = '24.
|
|
57
|
+
__version__ = '24.07.29'
|
|
58
58
|
|
|
59
59
|
_formy = _MODS.into(formy=__name__)
|
|
60
60
|
|
|
@@ -475,12 +475,11 @@ class LatLonBase(_NamedBase):
|
|
|
475
475
|
r = func_(phi2, self.phi, lam21, datum=D)
|
|
476
476
|
return r * (D.ellipsoid.a if radius is None else radius)
|
|
477
477
|
|
|
478
|
-
@
|
|
478
|
+
@property_ROnce
|
|
479
479
|
def Ecef(self):
|
|
480
480
|
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
481
481
|
'''
|
|
482
|
-
|
|
483
|
-
return E
|
|
482
|
+
return _MODS.ecef.EcefKarney
|
|
484
483
|
|
|
485
484
|
@Property_RO
|
|
486
485
|
def _Ecef_forward(self):
|
|
@@ -1535,7 +1534,7 @@ class LatLonBase(_NamedBase):
|
|
|
1535
1534
|
|
|
1536
1535
|
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see
|
|
1537
1536
|
functions L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
|
|
1538
|
-
@kwarg joined: Separator to join the lat-, longitude and
|
|
1537
|
+
@kwarg joined: Separator to join the lat-, longitude and height
|
|
1539
1538
|
strings (C{str} or C{None} or C{NN} for non-joined).
|
|
1540
1539
|
@kwarg m: Optional unit of the height (C{str}), use C{None} to
|
|
1541
1540
|
exclude height from the returned string.
|