pygeodesy 24.7.24__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.24.dist-info → PyGeodesy-24.8.4.dist-info}/METADATA +6 -6
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.4.dist-info}/RECORD +26 -26
- pygeodesy/__init__.py +4 -5
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/cartesianBase.py +2 -2
- pygeodesy/css.py +5 -5
- pygeodesy/ellipsoids.py +3 -3
- pygeodesy/formy.py +2 -2
- pygeodesy/gars.py +59 -52
- pygeodesy/geodesici.py +4 -10
- pygeodesy/geohash.py +484 -267
- pygeodesy/geoids.py +6 -2
- pygeodesy/heights.py +30 -40
- pygeodesy/internals.py +19 -6
- pygeodesy/karney.py +2 -2
- pygeodesy/latlonBase.py +2 -2
- pygeodesy/lazily.py +17 -16
- pygeodesy/ltp.py +2 -2
- pygeodesy/ltpTuples.py +6 -6
- pygeodesy/triaxials.py +4 -4
- pygeodesy/units.py +34 -17
- pygeodesy/wgrs.py +93 -83
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.7.24.dist-info → PyGeodesy-24.8.4.dist-info}/top_level.txt +0 -0
pygeodesy/geoids.py
CHANGED
|
@@ -117,7 +117,7 @@ except ImportError: # Python 3+
|
|
|
117
117
|
from io import BytesIO as _BytesIO # PYCHOK expected
|
|
118
118
|
|
|
119
119
|
__all__ = _ALL_LAZY.geoids
|
|
120
|
-
__version__ = '24.07.
|
|
120
|
+
__version__ = '24.07.25'
|
|
121
121
|
|
|
122
122
|
_assert_ = 'assert'
|
|
123
123
|
_bHASH_ = b'#'
|
|
@@ -287,7 +287,7 @@ class _GeoidBase(_HeightsBase):
|
|
|
287
287
|
|
|
288
288
|
def _called(self, llis, scipy, wrap=False, H=False):
|
|
289
289
|
# handle __call__
|
|
290
|
-
_H =
|
|
290
|
+
_H = self._heightOrthometric if H else None
|
|
291
291
|
_as, llis = _as_llis2(llis, Error=GeoidError)
|
|
292
292
|
hs, _w = [], _Wrap._latlonop(wrap)
|
|
293
293
|
_a, _h = hs.append, self._hGeoid
|
|
@@ -416,6 +416,10 @@ class _GeoidBase(_HeightsBase):
|
|
|
416
416
|
'''
|
|
417
417
|
return _height_called(self, lats, lons, Error=GeoidError, **wrap)
|
|
418
418
|
|
|
419
|
+
@property_ROver
|
|
420
|
+
def _heightOrthometric(self):
|
|
421
|
+
return _MODS.formy.heightOrthometric # overwrite property_ROver
|
|
422
|
+
|
|
419
423
|
def _hGeoid(self, lat, lon):
|
|
420
424
|
out = self.outside(lat, lon)
|
|
421
425
|
if out:
|
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
|
@@ -155,14 +155,14 @@ from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
|
155
155
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
156
156
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
157
157
|
from pygeodesy.props import deprecated_method, Property_RO, property_ROnce
|
|
158
|
-
from pygeodesy.units import
|
|
158
|
+
from pygeodesy.units import Azimuth as _Azi, Degrees as _Deg, Lat, Lon, \
|
|
159
159
|
Meter as _M, Meter2 as _M2, Number_
|
|
160
160
|
from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
161
161
|
|
|
162
162
|
# from math import fabs # from .utily
|
|
163
163
|
|
|
164
164
|
__all__ = _ALL_LAZY.karney
|
|
165
|
-
__version__ = '24.07.
|
|
165
|
+
__version__ = '24.07.25'
|
|
166
166
|
|
|
167
167
|
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
|
|
168
168
|
_perimeter_ = 'perimeter'
|
pygeodesy/latlonBase.py
CHANGED
|
@@ -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.07.
|
|
57
|
+
__version__ = '24.07.29'
|
|
58
58
|
|
|
59
59
|
_formy = _MODS.into(formy=__name__)
|
|
60
60
|
|
|
@@ -1534,7 +1534,7 @@ class LatLonBase(_NamedBase):
|
|
|
1534
1534
|
|
|
1535
1535
|
@kwarg form: The lat-/longitude C{B{form}at} to use (C{str}), see
|
|
1536
1536
|
functions L{pygeodesy.latDMS} or L{pygeodesy.lonDMS}.
|
|
1537
|
-
@kwarg joined: Separator to join the lat-, longitude and
|
|
1537
|
+
@kwarg joined: Separator to join the lat-, longitude and height
|
|
1538
1538
|
strings (C{str} or C{None} or C{NN} for non-joined).
|
|
1539
1539
|
@kwarg m: Optional unit of the height (C{str}), use C{None} to
|
|
1540
1540
|
exclude height from the returned string.
|
pygeodesy/lazily.py
CHANGED
|
@@ -31,8 +31,7 @@ from pygeodesy import internals as _internals, interns as _interns, \
|
|
|
31
31
|
_isfrozen # DON'T _lazy_import2
|
|
32
32
|
# from pygeodesy.errors import _error_init, _xkwds_item2 # _ALL_MODS
|
|
33
33
|
from pygeodesy.internals import _caller3, _dunder_nameof, _dunder_ismain, \
|
|
34
|
-
_headof,
|
|
35
|
-
_tailof # _Property_RO
|
|
34
|
+
_headof, printf, _Pythonarchine, _tailof # _Property_RO
|
|
36
35
|
from pygeodesy.interns import NN, _attribute_, _by_, _COLONSPACE_, _COMMASPACE_, \
|
|
37
36
|
_doesn_t_exist_, _DOT_, _EQUALSPACED_, _from_, \
|
|
38
37
|
_HASH_, _immutable_, _line_, _module_, _no_, _not_, \
|
|
@@ -290,7 +289,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
290
289
|
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
291
290
|
'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
|
|
292
291
|
geodsolve=_i('GeodesicSolve', 'GeodesicLineSolve', 'GeodSolve12Tuple'),
|
|
293
|
-
geohash=_i('Geohash', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple'),
|
|
292
|
+
geohash=_i('Geohash', 'Geohashed', 'GeohashError', 'Neighbors8Dict', 'Resolutions2Tuple', 'Sizes3Tuple'),
|
|
294
293
|
geoids=_i('GeoidError', 'GeoidG2012B', 'GeoidKarney', 'GeoidPGM', 'egmGeoidHeights',
|
|
295
294
|
'PGMError', 'GeoidHeight5Tuple'),
|
|
296
295
|
hausdorff=_i('Hausdorff', 'HausdorffDegrees', 'HausdorffError', 'HausdorffRadians',
|
|
@@ -368,7 +367,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
368
367
|
triaxials=_i('BetaOmega2Tuple', 'BetaOmega3Tuple', 'Jacobi2Tuple',
|
|
369
368
|
'JacobiConformal', 'JacobiConformalSpherical',
|
|
370
369
|
'Triaxial', 'Triaxial_', 'TriaxialError', 'Triaxials', 'hartzell4'),
|
|
371
|
-
units=_i('Band', 'Bearing', 'Bearing_', 'Bool',
|
|
370
|
+
units=_i('Azimuth', 'Band', 'Bearing', 'Bearing_', 'Bool',
|
|
372
371
|
'Degrees', 'Degrees_', 'Degrees2', 'Distance', 'Distance_', 'Easting', 'Epoch',
|
|
373
372
|
'Feet', 'FIx', 'Float_', 'Height', 'Height_', 'HeightX', 'Int_',
|
|
374
373
|
'Lam', 'Lamd', 'Lat', 'Lat_', 'Lon', 'Lon_',
|
|
@@ -522,7 +521,7 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
522
521
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
523
522
|
|
|
524
523
|
__all__ = _ALL_LAZY.lazily
|
|
525
|
-
__version__ = '24.
|
|
524
|
+
__version__ = '24.08.01'
|
|
526
525
|
|
|
527
526
|
|
|
528
527
|
def _ALL_OTHER(*objs):
|
|
@@ -862,13 +861,13 @@ def _lazy_module(name): # overwritten by _lazy_import2
|
|
|
862
861
|
#
|
|
863
862
|
# return _ALL_OTHER(*sm.values())
|
|
864
863
|
|
|
865
|
-
|
|
866
864
|
# del _i, _i0
|
|
867
865
|
|
|
868
866
|
# _ = _ALL_MODS.errors # force import pygeodesy.errors
|
|
869
867
|
|
|
870
868
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
871
869
|
|
|
870
|
+
from pygeodesy.internals import _versions
|
|
872
871
|
from timeit import timeit
|
|
873
872
|
|
|
874
873
|
def t1():
|
|
@@ -882,22 +881,24 @@ if _dunder_ismain(__name__): # PYCHOK no cover
|
|
|
882
881
|
|
|
883
882
|
t1 = timeit(t1, number=1000000)
|
|
884
883
|
t2 = timeit(t2, number=1000000)
|
|
885
|
-
|
|
886
|
-
printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, v)
|
|
884
|
+
printf('%.6f import vs %.6f _ALL_MODS: %.2fX, %s', t1, t2, t1 / t2, _versions())
|
|
887
885
|
|
|
888
886
|
# del t1, t2, timeit, v
|
|
889
887
|
|
|
890
|
-
# python3.
|
|
891
|
-
# 0.
|
|
888
|
+
# % python3.13 -W ignore -m pygeodesy.lazily
|
|
889
|
+
# 0.102670 import vs 0.076113 _ALL_MODS: 1.35X, pygeodesy 24.8.4 Python 3.13.0b4 64bit arm64 macOS 14.5
|
|
890
|
+
|
|
891
|
+
# % python3.12 -W ignore -m pygeodesy.lazily
|
|
892
|
+
# 0.132801 import vs 0.079125 _ALL_MODS: 1.68X, pygeodesy 24.8.4 Python 3.12.4 64bit arm64 macOS 14.5
|
|
892
893
|
|
|
893
|
-
# python3.11 -W ignore -m pygeodesy.lazily
|
|
894
|
-
# 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, Python 3.11.5 64bit arm64 macOS 14.4.1
|
|
894
|
+
# % python3.11 -W ignore -m pygeodesy.lazily
|
|
895
|
+
# 0.381723 import vs 0.251589 _ALL_MODS: 1.52X, pygeodesy 24.8.4 Python 3.11.5 64bit arm64 macOS 14.4.1
|
|
895
896
|
|
|
896
|
-
# python3.
|
|
897
|
-
# 0.
|
|
897
|
+
# % python3.8 -W ignore -m pygeodesy.lazily
|
|
898
|
+
# 0.570353 import vs 0.382842 _ALL_MODS: 1.49X, pygeodesy 24.8.4 Python 3.8.10 64bit arm64_x86_64 macOS 10.16
|
|
898
899
|
|
|
899
|
-
# python2 -m pygeodesy.lazily
|
|
900
|
-
# 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, Python 2.7.18 64bit arm64_x86_64 macOS 10.16
|
|
900
|
+
# % python2 -m pygeodesy.lazily
|
|
901
|
+
# 1.213805 import vs 0.474075 _ALL_MODS: 2.56X, pygeodesy 24.8.4 Python 2.7.18 64bit arm64_x86_64 macOS 10.16
|
|
901
902
|
|
|
902
903
|
# **) MIT License
|
|
903
904
|
#
|
pygeodesy/ltp.py
CHANGED
|
@@ -44,7 +44,7 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
|
|
|
44
44
|
# from math import fabs, floor as _floor # from .fmath, .fsums
|
|
45
45
|
|
|
46
46
|
__all__ = _ALL_LAZY.ltp
|
|
47
|
-
__version__ = '24.07.
|
|
47
|
+
__version__ = '24.07.25'
|
|
48
48
|
|
|
49
49
|
_height0_ = _height_ + _0_
|
|
50
50
|
_narrow_ = 'narrow'
|
|
@@ -730,7 +730,7 @@ class _ChLV(object):
|
|
|
730
730
|
# assert _args_kwds_names( ChLV.reverse)[1:4] == t
|
|
731
731
|
# assert _args_kwds_names(ChLVa.reverse)[1:4] == t
|
|
732
732
|
# assert _args_kwds_names(ChLVe.reverse)[1:4] == t
|
|
733
|
-
return t # overwrite
|
|
733
|
+
return t # overwrite property_ROver
|
|
734
734
|
|
|
735
735
|
def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
|
|
736
736
|
'''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
|
pygeodesy/ltpTuples.py
CHANGED
|
@@ -28,15 +28,15 @@ from pygeodesy.namedTuples import LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
|
|
|
28
28
|
from pygeodesy.props import deprecated_method, deprecated_Property_RO, \
|
|
29
29
|
Property_RO, property_RO
|
|
30
30
|
from pygeodesy.streprs import Fmt, fstr, strs, _xzipairs
|
|
31
|
-
from pygeodesy.units import Bearing, Degrees, Degrees_, Height,
|
|
32
|
-
_isMeter, Lat, Lon, Meter, Meter_
|
|
31
|
+
from pygeodesy.units import Azimuth, Bearing, Degrees, Degrees_, Height, \
|
|
32
|
+
_isDegrees, _isMeter, Lat, Lon, Meter, Meter_
|
|
33
33
|
from pygeodesy.utily import atan2d, atan2b, sincos2_, sincos2d_, cos, radians
|
|
34
34
|
from pygeodesy.vector3d import Vector3d
|
|
35
35
|
|
|
36
36
|
# from math import cos, radians # from .utily
|
|
37
37
|
|
|
38
38
|
__all__ = _ALL_LAZY.ltpTuples
|
|
39
|
-
__version__ = '24.
|
|
39
|
+
__version__ = '24.07.25'
|
|
40
40
|
|
|
41
41
|
_aer_ = 'aer'
|
|
42
42
|
_alt_ = 'alt'
|
|
@@ -93,7 +93,7 @@ def _xyz2aer4(inst):
|
|
|
93
93
|
'''(INTERNAL) Convert C{(x, y, z}) to C{(A, E, R)}.
|
|
94
94
|
'''
|
|
95
95
|
x, y, z, _ = inst.xyz4
|
|
96
|
-
A =
|
|
96
|
+
A = Azimuth(atan2b(x, y))
|
|
97
97
|
E = Degrees(elevation=atan2d(z, hypot(x, y)))
|
|
98
98
|
R = Meter(slantrange=hypot_(x, y, z))
|
|
99
99
|
return Aer4Tuple(A, E, R, inst.ltp, name=inst.name)
|
|
@@ -268,7 +268,7 @@ class Aer(_AbcBase):
|
|
|
268
268
|
'''
|
|
269
269
|
if _isDegrees(azimuth_aer):
|
|
270
270
|
aer = None
|
|
271
|
-
t = (
|
|
271
|
+
t = (Azimuth(azimuth_aer),
|
|
272
272
|
Degrees_(elevation=elevation, low=_N_90_0, high=_90_0),
|
|
273
273
|
Meter_(slantrange=slantrange), ltp)
|
|
274
274
|
else: # PYCHOK no cover
|
|
@@ -421,7 +421,7 @@ class Attitude4Tuple(_NamedTuple):
|
|
|
421
421
|
the attitude of a plane or camera.
|
|
422
422
|
'''
|
|
423
423
|
_Names_ = (_alt_, _tilt_, _yaw_, _roll_)
|
|
424
|
-
_Units_ = ( Meter,
|
|
424
|
+
_Units_ = ( Meter, Degrees, Bearing, Degrees)
|
|
425
425
|
|
|
426
426
|
@Property_RO
|
|
427
427
|
def atyr(self):
|
pygeodesy/triaxials.py
CHANGED
|
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
|
|
|
59
59
|
from math import atan2, fabs, sqrt
|
|
60
60
|
|
|
61
61
|
__all__ = _ALL_LAZY.triaxials
|
|
62
|
-
__version__ = '24.07.
|
|
62
|
+
__version__ = '24.07.29'
|
|
63
63
|
|
|
64
64
|
_not_ordered_ = _not_('ordered')
|
|
65
65
|
_omega_ = 'omega'
|
|
@@ -364,7 +364,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
364
364
|
def _Elliptic(self):
|
|
365
365
|
'''(INTERNAL) Get class L{Elliptic}, I{once}.
|
|
366
366
|
'''
|
|
367
|
-
return _MODS.elliptic.Elliptic # overwrite
|
|
367
|
+
return _MODS.elliptic.Elliptic # overwrite property_ROver
|
|
368
368
|
|
|
369
369
|
def hartzell4(self, pov, los=False, **name):
|
|
370
370
|
'''Compute the intersection of this triaxial's surface with a Line-Of-Sight
|
|
@@ -753,7 +753,7 @@ class Triaxial(Triaxial_):
|
|
|
753
753
|
return self.height4(x_xyz, y, z, **normal_eps_name)
|
|
754
754
|
|
|
755
755
|
def forwardLatLon(self, lat, lon, height=0, **name):
|
|
756
|
-
'''Convert I{geodetic} lat-, longitude and
|
|
756
|
+
'''Convert I{geodetic} lat-, longitude and height to cartesian.
|
|
757
757
|
|
|
758
758
|
@arg lat: Geodetic latitude (C{degrees}).
|
|
759
759
|
@arg lon: Geodetic longitude (C{degrees}).
|
|
@@ -769,7 +769,7 @@ class Triaxial(Triaxial_):
|
|
|
769
769
|
return self._forwardLatLon3(height, name, *sincos2d_(lat, lon))
|
|
770
770
|
|
|
771
771
|
def forwardLatLon_(self, slat, clat, slon, clon, height=0, **name):
|
|
772
|
-
'''Convert I{geodetic} lat-, longitude and
|
|
772
|
+
'''Convert I{geodetic} lat-, longitude and height to cartesian.
|
|
773
773
|
|
|
774
774
|
@arg slat: Geodetic latitude C{sin(lat)} (C{scalar}).
|
|
775
775
|
@arg clat: Geodetic latitude C{cos(lat)} (C{scalar}).
|
pygeodesy/units.py
CHANGED
|
@@ -11,11 +11,11 @@ from pygeodesy.constants import EPS, EPS1, PI, PI2, PI_2, _umod_360, _0_0, \
|
|
|
11
11
|
_0_001, _0_5, INT0 # PYCHOK for .mgrs, .namedTuples
|
|
12
12
|
from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, _toDMS
|
|
13
13
|
from pygeodesy.errors import _AssertionError, TRFError, UnitError, _xattr, _xcallable
|
|
14
|
-
from pygeodesy.interns import NN, _band_, _bearing_, _COMMASPACE_,
|
|
15
|
-
_degrees2_, _distance_, _E_, _easting_,
|
|
16
|
-
_feet_, _height_, _lam_, _lat_, _LatLon_,
|
|
17
|
-
_meter_, _meter2_, _N_, _negative_, _northing_,
|
|
18
|
-
_NSEW_, _number_, _PERCENT_, _phi_, _precision_, \
|
|
14
|
+
from pygeodesy.interns import NN, _azimuth_, _band_, _bearing_, _COMMASPACE_, \
|
|
15
|
+
_degrees_, _degrees2_, _distance_, _E_, _easting_, \
|
|
16
|
+
_epoch_, _EW_, _feet_, _height_, _lam_, _lat_, _LatLon_, \
|
|
17
|
+
_lon_, _meter_, _meter2_, _N_, _negative_, _northing_, \
|
|
18
|
+
_NS_, _NSEW_, _number_, _PERCENT_, _phi_, _precision_, \
|
|
19
19
|
_radians_, _radians2_, _radius_, _S_, _scalar_, \
|
|
20
20
|
_units_, _W_, _zone_, _std_ # PYCHOK used!
|
|
21
21
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
@@ -24,10 +24,10 @@ from pygeodesy.props import Property_RO
|
|
|
24
24
|
# from pygeodesy.streprs import Fmt, fstr # from .unitsBase
|
|
25
25
|
from pygeodesy.unitsBase import Float, Int, _NamedUnit, Radius, Str, Fmt, fstr
|
|
26
26
|
|
|
27
|
-
from math import degrees, radians
|
|
27
|
+
from math import degrees, isnan, radians
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.units
|
|
30
|
-
__version__ = '24.
|
|
30
|
+
__version__ = '24.08.02'
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class Float_(Float):
|
|
@@ -339,18 +339,35 @@ class Radians2(Float_):
|
|
|
339
339
|
return Float_.__new__(cls, arg=arg, name=name, low=_0_0, **Error_name_arg)
|
|
340
340
|
|
|
341
341
|
|
|
342
|
+
def _Degrees_new(cls, **arg_name_suffix_clip_Error_name_arg):
|
|
343
|
+
d = Degrees.__new__(cls, **arg_name_suffix_clip_Error_name_arg)
|
|
344
|
+
b = _umod_360(d) # 0 <= b < 360
|
|
345
|
+
return d if b == d else Degrees.__new__(cls, arg=b, name=d.name)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class Azimuth(Degrees):
|
|
349
|
+
'''Named C{float} representing an azimuth in compass C{degrees} from (true) North.
|
|
350
|
+
'''
|
|
351
|
+
_ddd_ = 1
|
|
352
|
+
_suf_ = _W_, S_NUL, _E_ # no zero suffix
|
|
353
|
+
|
|
354
|
+
def __new__(cls, arg=None, name=_azimuth_, **clip_Error_name_arg):
|
|
355
|
+
'''New, named L{Azimuth} with optional suffix 'E' for clockwise or 'W' for
|
|
356
|
+
anti-clockwise, see L{Degrees}.
|
|
357
|
+
'''
|
|
358
|
+
return _Degrees_new(cls, arg=arg, name=name, suffix=_EW_, **clip_Error_name_arg)
|
|
359
|
+
|
|
360
|
+
|
|
342
361
|
class Bearing(Degrees):
|
|
343
362
|
'''Named C{float} representing a bearing in compass C{degrees} from (true) North.
|
|
344
363
|
'''
|
|
345
364
|
_ddd_ = 1
|
|
346
365
|
_suf_ = _N_ * 3 # always suffix N
|
|
347
366
|
|
|
348
|
-
def __new__(cls, arg=None, name=_bearing_,
|
|
367
|
+
def __new__(cls, arg=None, name=_bearing_, **clip_Error_name_arg):
|
|
349
368
|
'''New, named L{Bearing}, see L{Degrees}.
|
|
350
369
|
'''
|
|
351
|
-
|
|
352
|
-
b = _umod_360(d) # 0 <= b < 360
|
|
353
|
-
return d if b == d else Degrees.__new__(cls, arg=b, name=d.name)
|
|
370
|
+
return _Degrees_new(cls, arg=arg, name=name, suffix=_N_, **clip_Error_name_arg)
|
|
354
371
|
|
|
355
372
|
|
|
356
373
|
class Bearing_(Radians):
|
|
@@ -782,7 +799,7 @@ class Zone(Int):
|
|
|
782
799
|
|
|
783
800
|
|
|
784
801
|
_ScalarU = Float, Float_, Scalar, Scalar_
|
|
785
|
-
_Degrees = (Bearing, Bearing_, Degrees, Degrees_) + _ScalarU
|
|
802
|
+
_Degrees = (Azimuth, Bearing, Bearing_, Degrees, Degrees_) + _ScalarU
|
|
786
803
|
_Meters = (Distance, Distance_, Meter, Meter_) + _ScalarU
|
|
787
804
|
_Radians = (Radians, Radians_) + _ScalarU # PYCHOK unused
|
|
788
805
|
_Radii = _Meters + (Radius, Radius_)
|
|
@@ -794,7 +811,7 @@ def _isDegrees(obj):
|
|
|
794
811
|
|
|
795
812
|
|
|
796
813
|
def _isHeight(obj):
|
|
797
|
-
# Check for valid
|
|
814
|
+
# Check for valid height types.
|
|
798
815
|
return isinstance(obj, _Meters) or _isScalar(obj)
|
|
799
816
|
|
|
800
817
|
|
|
@@ -823,13 +840,13 @@ def _toUnit(Unit, arg, name=NN, **Error):
|
|
|
823
840
|
|
|
824
841
|
|
|
825
842
|
def _xlimits(arg, low, high, g=False):
|
|
826
|
-
'''(INTERNAL) Check C{low <=
|
|
843
|
+
'''(INTERNAL) Check C{low <= arg <= high}.
|
|
827
844
|
'''
|
|
828
|
-
if (low is not None) and arg < low:
|
|
845
|
+
if (low is not None) and (arg < low or isnan(arg)):
|
|
829
846
|
if g:
|
|
830
847
|
low = Fmt.g(low, prec=6, ints=isinstance(arg, Epoch))
|
|
831
848
|
t = Fmt.limit(below=low)
|
|
832
|
-
elif (high is not None) and arg > high:
|
|
849
|
+
elif (high is not None) and (arg > high or isnan(arg)):
|
|
833
850
|
if g:
|
|
834
851
|
high = Fmt.g(high, prec=6, ints=isinstance(arg, Epoch))
|
|
835
852
|
t = Fmt.limit(above=high)
|
|
@@ -847,7 +864,7 @@ def _std_repr(*Classes):
|
|
|
847
864
|
if _getenv(env, _std_).lower() != _std_:
|
|
848
865
|
C._std_repr = False
|
|
849
866
|
|
|
850
|
-
_std_repr(Bearing, Bool, Degrees, Float, Int, Meter, Radians, Str) # PYCHOK expected
|
|
867
|
+
_std_repr(Azimuth, Bearing, Bool, Degrees, Float, Int, Meter, Radians, Str) # PYCHOK expected
|
|
851
868
|
del _std_repr
|
|
852
869
|
|
|
853
870
|
__all__ += _ALL_DOCS(_NamedUnit)
|