pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.1__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.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/RECORD +57 -57
- pygeodesy/__init__.py +4 -4
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +4 -4
- pygeodesy/basics.py +39 -5
- pygeodesy/booleans.py +3 -3
- pygeodesy/constants.py +3 -3
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/ecef.py +22 -21
- pygeodesy/ellipsoidalBase.py +15 -16
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoids.py +6 -5
- pygeodesy/errors.py +19 -9
- pygeodesy/etm.py +16 -21
- pygeodesy/fmath.py +9 -20
- pygeodesy/formy.py +60 -74
- pygeodesy/frechet.py +11 -11
- pygeodesy/fsums.py +59 -25
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +3 -5
- pygeodesy/geodsolve.py +2 -2
- pygeodesy/geohash.py +14 -14
- pygeodesy/hausdorff.py +12 -12
- pygeodesy/heights.py +5 -5
- pygeodesy/internals.py +3 -3
- pygeodesy/karney.py +8 -7
- pygeodesy/lazily.py +2 -2
- pygeodesy/ltp.py +62 -44
- pygeodesy/ltpTuples.py +202 -147
- pygeodesy/mgrs.py +24 -24
- pygeodesy/named.py +68 -70
- pygeodesy/nvectorBase.py +2 -2
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +10 -10
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +13 -10
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +14 -14
- pygeodesy/sphericalBase.py +17 -21
- pygeodesy/sphericalTrigonometry.py +17 -17
- pygeodesy/trf.py +9 -7
- pygeodesy/triaxials.py +2 -2
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +3 -3
- pygeodesy/utm.py +152 -156
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +102 -106
- pygeodesy/webmercator.py +43 -51
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/geohash.py
CHANGED
|
@@ -297,20 +297,20 @@ class Geohash(Str):
|
|
|
297
297
|
using function L{pygeodesy.equirectangular}.
|
|
298
298
|
|
|
299
299
|
@arg other: The other geohash (L{Geohash}, C{LatLon} or C{str}).
|
|
300
|
-
@kwarg radius: Mean earth radius, ellipsoid or datum
|
|
301
|
-
|
|
302
|
-
L{
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
300
|
+
@kwarg radius: Mean earth radius, ellipsoid or datum (C{meter},
|
|
301
|
+
L{Ellipsoid}, L{Ellipsoid2}, L{Datum} or
|
|
302
|
+
L{a_f2Tuple}) or C{None}, see function
|
|
303
|
+
L{pygeodesy.equirectangular}.
|
|
304
|
+
@kwarg adjust_limit_wrap: Optional keyword arguments for function
|
|
305
|
+
L{pygeodesy.equirectangular4}, overriding defaults
|
|
306
|
+
C{B{adjust}=False, B{limit}=None} and C{B{wrap}=False}.
|
|
307
307
|
|
|
308
308
|
@return: Distance (C{meter}, same units as B{C{radius}} or the
|
|
309
309
|
ellipsoid or datum axes or C{radians I{squared}} if
|
|
310
310
|
B{C{radius}} is C{None} or C{0}).
|
|
311
311
|
|
|
312
|
-
@raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon}
|
|
313
|
-
|
|
312
|
+
@raise TypeError: The B{C{other}} is not a L{Geohash}, C{LatLon} or
|
|
313
|
+
C{str} or invalid B{C{radius}}.
|
|
314
314
|
|
|
315
315
|
@see: U{Local, flat earth approximation
|
|
316
316
|
<https://www.EdWilliams.org/avform.htm#flat>}, functions
|
|
@@ -319,7 +319,7 @@ class Geohash(Str):
|
|
|
319
319
|
kwds = _xkwds(adjust_limit_wrap, adjust=False, limit=None, wrap=False)
|
|
320
320
|
m = self._formy
|
|
321
321
|
return m.equirectangular( *lls, radius=radius, **kwds) if radius else \
|
|
322
|
-
m.
|
|
322
|
+
m.equirectangular4(*lls, **kwds).distance2
|
|
323
323
|
|
|
324
324
|
def euclideanTo(self, other, **radius_adjust_wrap):
|
|
325
325
|
'''Approximate the distance between this and an other geohash using
|
|
@@ -645,8 +645,8 @@ def distance1(geohash1, geohash2):
|
|
|
645
645
|
|
|
646
646
|
@deprecated_function
|
|
647
647
|
def distance2(geohash1, geohash2):
|
|
648
|
-
'''DEPRECATED, use L{geohash.
|
|
649
|
-
return
|
|
648
|
+
'''DEPRECATED, use L{geohash.equirectangular4}.'''
|
|
649
|
+
return equirectangular4(geohash1, geohash2)
|
|
650
650
|
|
|
651
651
|
|
|
652
652
|
@deprecated_function
|
|
@@ -718,7 +718,7 @@ def encode(lat, lon, precision=None):
|
|
|
718
718
|
return NN.join(gh)
|
|
719
719
|
|
|
720
720
|
|
|
721
|
-
def
|
|
721
|
+
def equirectangular4(geohash1, geohash2, radius=R_M):
|
|
722
722
|
'''Approximate the distance between two geohashes using the
|
|
723
723
|
L{pygeodesy.equirectangular} formula.
|
|
724
724
|
|
|
@@ -891,7 +891,7 @@ def vincentys_(geohash1, geohash2, **radius_wrap):
|
|
|
891
891
|
|
|
892
892
|
__all__ += _ALL_OTHER(bounds, # functions
|
|
893
893
|
decode, decode2, decode_error, distance_,
|
|
894
|
-
encode,
|
|
894
|
+
encode, equirectangular4, euclidean_, haversine_,
|
|
895
895
|
neighbors, precision, resolution2, sizes, vincentys_)
|
|
896
896
|
|
|
897
897
|
# **) MIT License
|
pygeodesy/hausdorff.py
CHANGED
|
@@ -77,7 +77,7 @@ from pygeodesy.lazily import _ALL_LAZY, _FOR_DOCS
|
|
|
77
77
|
from pygeodesy.named import _name2__, _Named, _NamedTuple, _Pass
|
|
78
78
|
# from pygeodesy.namedTuples import PhiLam2Tuple # from .points
|
|
79
79
|
from pygeodesy.points import _distanceTo, points2 as _points2, PhiLam2Tuple, radians
|
|
80
|
-
from pygeodesy.props import Property_RO, property_doc_, property_RO
|
|
80
|
+
from pygeodesy.props import Property, Property_RO, property_doc_, property_RO
|
|
81
81
|
from pygeodesy.units import Float, Number_, _xUnit, _xUnits
|
|
82
82
|
from pygeodesy.unitsBase import _Str_degrees, _Str_degrees2, _Str_meter, _Str_NN, \
|
|
83
83
|
_Str_radians, _Str_radians2
|
|
@@ -86,7 +86,7 @@ from pygeodesy.unitsBase import _Str_degrees, _Str_degrees2, _Str_meter, _Str_NN
|
|
|
86
86
|
from random import Random
|
|
87
87
|
|
|
88
88
|
__all__ = _ALL_LAZY.hausdorff
|
|
89
|
-
__version__ = '24.05.
|
|
89
|
+
__version__ = '24.05.26'
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
class HausdorffError(PointsError):
|
|
@@ -179,14 +179,14 @@ class Hausdorff(_Named):
|
|
|
179
179
|
return self._func(point1.lat, point1.lon,
|
|
180
180
|
point2.lat, point2.lon, **self._kwds)
|
|
181
181
|
|
|
182
|
-
@
|
|
182
|
+
@Property
|
|
183
183
|
def _func(self):
|
|
184
184
|
'''(INTERNAL) I{Must be overloaded}.'''
|
|
185
|
-
|
|
185
|
+
self._notOverloaded(**self.kwds)
|
|
186
186
|
|
|
187
|
-
@_func.
|
|
187
|
+
@_func.setter_ # PYCHOK setter_underscore!
|
|
188
188
|
def _func(self, func):
|
|
189
|
-
_formy._Propy(
|
|
189
|
+
return _formy._Propy(func, 4, self.kwds)
|
|
190
190
|
|
|
191
191
|
def _hausdorff_(self, point2s, both, early, distance):
|
|
192
192
|
_, ps2 = self._points2(point2s)
|
|
@@ -341,14 +341,14 @@ class _HausdorffMeterRadians(Hausdorff):
|
|
|
341
341
|
'''
|
|
342
342
|
return self._hausdorff_(point2s, True, early, _formy._radistance(self))
|
|
343
343
|
|
|
344
|
-
@
|
|
344
|
+
@Property
|
|
345
345
|
def _func_(self):
|
|
346
346
|
'''(INTERNAL) I{Must be overloaded}.'''
|
|
347
|
-
|
|
347
|
+
self._notOverloaded(**self.kwds)
|
|
348
348
|
|
|
349
|
-
@_func_.
|
|
349
|
+
@_func_.setter_ # PYCHOK setter_underscore!
|
|
350
350
|
def _func_(self, func):
|
|
351
|
-
_formy._Propy(
|
|
351
|
+
return _formy._Propy(func, 3, self.kwds)
|
|
352
352
|
|
|
353
353
|
|
|
354
354
|
class HausdorffCosineAndoyerLambert(_HausdorffMeterRadians):
|
|
@@ -462,7 +462,7 @@ class HausdorffDistanceTo(Hausdorff):
|
|
|
462
462
|
|
|
463
463
|
class HausdorffEquirectangular(Hausdorff):
|
|
464
464
|
'''Compute the C{Hausdorff} distance based on the C{equirectangular} distance
|
|
465
|
-
in C{radians squared} like function L{pygeodesy.
|
|
465
|
+
in C{radians squared} like function L{pygeodesy.equirectangular}.
|
|
466
466
|
'''
|
|
467
467
|
_units = _Str_degrees2
|
|
468
468
|
|
|
@@ -471,7 +471,7 @@ class HausdorffEquirectangular(Hausdorff):
|
|
|
471
471
|
|
|
472
472
|
@kwarg seed_name__adjust_limit_wrap: Optional C{B{seed}=None} and
|
|
473
473
|
C{B{name}=NN} and keyword arguments for function
|
|
474
|
-
L{pygeodesy.
|
|
474
|
+
L{pygeodesy.equirectangular} I{with default}
|
|
475
475
|
C{B{limit}=0} for I{backward compatibility}.
|
|
476
476
|
|
|
477
477
|
@see: L{Hausdorff.__init__} for details about B{C{point1s}},
|
pygeodesy/heights.py
CHANGED
|
@@ -75,7 +75,7 @@ from pygeodesy.errors import _AssertionError, LenError, PointsError, \
|
|
|
75
75
|
_SciPyIssue, _xattr, _xkwds, _xkwds_get, _xkwds_item2
|
|
76
76
|
# from pygeodesy.fmath import fidw # _MODS
|
|
77
77
|
# from pygeodesy.formy import cosineAndoyerLambert, cosineForsytheAndoyerLambert, \
|
|
78
|
-
# cosineLaw,
|
|
78
|
+
# cosineLaw, equirectangular4, euclidean, flatLocal, \
|
|
79
79
|
# flatPolar, haversine, thomas, vincentys # _MODS
|
|
80
80
|
# from pygeodesy.internals import _version2 # _MODS
|
|
81
81
|
from pygeodesy.interns import NN, _COMMASPACE_, _cubic_, _insufficient_, _linear_, \
|
|
@@ -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.05.
|
|
94
|
+
__version__ = '24.05.25'
|
|
95
95
|
|
|
96
96
|
_error_ = 'error'
|
|
97
97
|
_llis_ = 'llis'
|
|
@@ -898,14 +898,14 @@ class HeightIDWequirectangular(_HeightIDW):
|
|
|
898
898
|
'''Height interpolator using U{Inverse Distance Weighting
|
|
899
899
|
<https://WikiPedia.org/wiki/Inverse_distance_weighting>} (IDW) and
|
|
900
900
|
the I{angular} distance in C{radians squared} like function
|
|
901
|
-
L{pygeodesy.
|
|
901
|
+
L{pygeodesy.equirectangular4}.
|
|
902
902
|
'''
|
|
903
903
|
def __init__(self, knots, beta=2, **name__adjust_limit_wrap): # XXX beta=1
|
|
904
904
|
'''New L{HeightIDWequirectangular} interpolator.
|
|
905
905
|
|
|
906
906
|
@kwarg name__adjust_limit_wrap: Optional C{B{name}=NN} for this
|
|
907
907
|
height interpolator (C{str}) and keyword arguments
|
|
908
|
-
for function L{pygeodesy.
|
|
908
|
+
for function L{pygeodesy.equirectangular4}.
|
|
909
909
|
|
|
910
910
|
@see: L{Here<_HeightIDW.__init__>} for further details.
|
|
911
911
|
'''
|
|
@@ -914,7 +914,7 @@ class HeightIDWequirectangular(_HeightIDW):
|
|
|
914
914
|
def _distances(self, x, y):
|
|
915
915
|
'''(INTERNAL) Yield distances to C{(x, y)}.
|
|
916
916
|
'''
|
|
917
|
-
_f, kwds = self._formy.
|
|
917
|
+
_f, kwds = self._formy.equirectangular4, self._kwds
|
|
918
918
|
try:
|
|
919
919
|
for i, k in enumerate(self._knots):
|
|
920
920
|
yield _f(y, x, k.lat, k.lon, **kwds).distance2
|
pygeodesy/internals.py
CHANGED
|
@@ -543,15 +543,15 @@ def _version_ints(vs):
|
|
|
543
543
|
|
|
544
544
|
|
|
545
545
|
__all__ = tuple(map(_dunder_nameof, (machine, print_, printf)))
|
|
546
|
-
__version__ = '24.05.
|
|
546
|
+
__version__ = '24.05.25'
|
|
547
547
|
|
|
548
548
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
549
549
|
|
|
550
550
|
from pygeodesy import _isfrozen, isLazy, version as vs
|
|
551
551
|
|
|
552
552
|
print_(_pygeodesy_, vs, *(_Pythonarchine() + _osversion2()
|
|
553
|
-
+ ['
|
|
554
|
-
'isLazy',
|
|
553
|
+
+ ['_isfrozen', _isfrozen,
|
|
554
|
+
'isLazy', isLazy]))
|
|
555
555
|
|
|
556
556
|
# **) MIT License
|
|
557
557
|
#
|
pygeodesy/karney.py
CHANGED
|
@@ -143,12 +143,13 @@ 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,
|
|
146
|
+
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
|
|
147
147
|
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
148
148
|
# from pygeodesy.internals import _version_info # from .basics
|
|
149
|
-
from pygeodesy.interns import
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
from pygeodesy.interns import _2_, _a12_, _area_, _azi2_, _azi12_, _composite_, \
|
|
150
|
+
_lat1_, _lat2_, _lon1_, _lon2_, _m12_, _M12_, \
|
|
151
|
+
_M21_, _number_, _s12_, _S12_, _UNDER_, \
|
|
152
|
+
_BAR_, NN # PYCHOK used!
|
|
152
153
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
153
154
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
154
155
|
from pygeodesy.props import deprecated_method, Property_RO
|
|
@@ -159,7 +160,7 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
159
160
|
# from math import fabs # from .utily
|
|
160
161
|
|
|
161
162
|
__all__ = _ALL_LAZY.karney
|
|
162
|
-
__version__ = '24.05.
|
|
163
|
+
__version__ = '24.05.31'
|
|
163
164
|
|
|
164
165
|
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
|
|
165
166
|
_perimeter_ = 'perimeter'
|
|
@@ -171,7 +172,7 @@ class _GTuple(_NamedTuple): # in .testNamedTuples
|
|
|
171
172
|
def toGDict(self, **updates): # NO name=NN
|
|
172
173
|
'''Convert this C{*Tuple} to a L{GDict}.
|
|
173
174
|
|
|
174
|
-
@kwarg updates: Optional items to apply (C{
|
|
175
|
+
@kwarg updates: Optional items to apply (C{name=value} pairs)
|
|
175
176
|
'''
|
|
176
177
|
r = GDict(_zip(self._Names_, self)) # strict=True
|
|
177
178
|
if updates:
|
|
@@ -845,7 +846,7 @@ def _sum2_(s, t, *vs, **x):
|
|
|
845
846
|
|
|
846
847
|
@note: NOT "error-free", see C{pygeodesy.test/testKarney.py}.
|
|
847
848
|
'''
|
|
848
|
-
x =
|
|
849
|
+
x = _xkwds_get1(x, x=_1_0)
|
|
849
850
|
p = x != _1_0
|
|
850
851
|
|
|
851
852
|
_s2, _u0 = _sum2, unsigned0
|
pygeodesy/lazily.py
CHANGED
|
@@ -269,7 +269,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
269
269
|
'antipode', 'antipode_', 'bearing', 'bearing_',
|
|
270
270
|
'compassAngle', 'cosineForsytheAndoyerLambert', 'cosineForsytheAndoyerLambert_',
|
|
271
271
|
'cosineAndoyerLambert', 'cosineAndoyerLambert_', 'cosineLaw', 'cosineLaw_',
|
|
272
|
-
'equirectangular', '
|
|
272
|
+
'equirectangular', 'equirectangular4', 'euclidean', 'euclidean_',
|
|
273
273
|
'excessAbc_', 'excessCagnoli_', 'excessGirard_', 'excessLHuilier_',
|
|
274
274
|
'excessKarney', 'excessKarney_', 'excessQuad', 'excessQuad_',
|
|
275
275
|
'flatLocal', 'flatLocal_', 'flatPolar', 'flatPolar_',
|
|
@@ -421,7 +421,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
421
421
|
'R_M', 'R_MA', 'R_MB', 'R_KM', 'R_NM', 'R_SM', 'R_FM', 'R_VM'),
|
|
422
422
|
deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ...
|
|
423
423
|
'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ... ellipsoidal, spherical flavors
|
|
424
|
-
'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular3',
|
|
424
|
+
'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular_', 'equirectangular3',
|
|
425
425
|
'excessAbc', 'excessGirard', 'excessLHuilier',
|
|
426
426
|
'false2f', 'falsed2f', 'float0', 'fStr', 'fStrzs', 'hypot3',
|
|
427
427
|
'inStr', 'isenclosedby', 'istuplist',
|
pygeodesy/ltp.py
CHANGED
|
@@ -13,7 +13,7 @@ and L{ChLVe} and L{Ltp}, L{ChLV}, L{LocalError}, L{Attitude} and L{Frustum}.
|
|
|
13
13
|
# make sure int/int division yields float quotient, see .basics
|
|
14
14
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
15
15
|
|
|
16
|
-
from pygeodesy.basics import _args_kwds_names,
|
|
16
|
+
from pygeodesy.basics import _args_kwds_names, map1, map2, _xsubclassof # .datums
|
|
17
17
|
from pygeodesy.constants import EPS, INT0, _umod_360, _0_0, _0_01, _0_5, _1_0, \
|
|
18
18
|
_2_0, _60_0, _90_0, _100_0, _180_0, _3600_0, \
|
|
19
19
|
_N_1_0 # PYCHOK used!
|
|
@@ -29,7 +29,7 @@ from pygeodesy.interns import _0_, _COMMASPACE_, _DOT_, _ecef_, _height_, _M_, \
|
|
|
29
29
|
from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
|
|
30
30
|
ChLVYX2Tuple, Footprint5Tuple, Local9Tuple, \
|
|
31
31
|
ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
|
|
32
|
-
from pygeodesy.named import _name__, _NamedBase, notOverloaded
|
|
32
|
+
from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
|
|
33
33
|
from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
|
|
34
34
|
from pygeodesy.props import Property, Property_RO, property_doc_, property_RO, \
|
|
35
35
|
_update_all
|
|
@@ -42,25 +42,15 @@ from pygeodesy.vector3d import _ALL_LAZY, Vector3d
|
|
|
42
42
|
# from math import fabs, floor as _floor # from .fmath, .fsums
|
|
43
43
|
|
|
44
44
|
__all__ = _ALL_LAZY.ltp
|
|
45
|
-
__version__ = '24.
|
|
45
|
+
__version__ = '24.05.31'
|
|
46
46
|
|
|
47
47
|
_height0_ = _height_ + _0_
|
|
48
48
|
_narrow_ = 'narrow'
|
|
49
49
|
_wide_ = 'wide'
|
|
50
|
-
_Xyz_ = 'Xyz'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def _fov_2(**fov):
|
|
54
|
-
# Half a field-of-view angle in C{degrees}.
|
|
55
|
-
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
56
|
-
if EPS < f < _90_0:
|
|
57
|
-
return f
|
|
58
|
-
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
59
|
-
raise LocalError(txt=t, **fov)
|
|
60
50
|
|
|
61
51
|
|
|
62
52
|
class Attitude(_NamedBase):
|
|
63
|
-
'''The
|
|
53
|
+
'''The pose of a plane or camera in space.
|
|
64
54
|
'''
|
|
65
55
|
_alt = Meter( alt =_0_0)
|
|
66
56
|
_roll = Degrees(roll=_0_0)
|
|
@@ -70,9 +60,9 @@ class Attitude(_NamedBase):
|
|
|
70
60
|
def __init__(self, alt_attitude=INT0, tilt=INT0, yaw=INT0, roll=INT0, **name):
|
|
71
61
|
'''New L{Attitude}.
|
|
72
62
|
|
|
73
|
-
@kwarg alt_attitude:
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
@kwarg alt_attitude: Altitude (C{meter}) above earth or previous attitude
|
|
64
|
+
(L{Attitude} or L{Attitude4Tuple}) with the C{B{alt}itude},
|
|
65
|
+
B{C{tilt}}, B{C{yaw}} and B{C{roll}}.
|
|
76
66
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees180}), negative down
|
|
77
67
|
(clockwise rotation along and around the x- or East axis).
|
|
78
68
|
@kwarg yaw: Bearing, heading (compass C{degrees360}), clockwise from North
|
|
@@ -149,23 +139,26 @@ class Attitude(_NamedBase):
|
|
|
149
139
|
|
|
150
140
|
bank = roll
|
|
151
141
|
|
|
152
|
-
def rotate(self, x_xyz, y=None, z=None, Vector=None, **
|
|
142
|
+
def rotate(self, x_xyz, y=None, z=None, Vector=None, **name_Vector_kwds):
|
|
153
143
|
'''Transform a (local) cartesian by this attitude's matrix.
|
|
154
144
|
|
|
155
|
-
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector
|
|
156
|
-
|
|
145
|
+
@arg x_xyz: X component of vector (C{scalar}) or (3-D) vector (C{Cartesian},
|
|
146
|
+
L{Vector3d} or L{Vector3Tuple}).
|
|
157
147
|
@kwarg y: Y component of vector (C{scalar}), same units as B{C{x}}.
|
|
158
148
|
@kwarg z: Z component of vector (C{scalar}), same units as B{C{x}}.
|
|
159
|
-
@kwarg Vector: Class to return transformed point (C{Cartesian},
|
|
160
|
-
|
|
161
|
-
@kwarg
|
|
162
|
-
|
|
149
|
+
@kwarg Vector: Class to return transformed point (C{Cartesian}, L{Vector3d}
|
|
150
|
+
or C{Vector3Tuple}) or C{None}.
|
|
151
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
152
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
153
|
+
C{B{Vector} is None}.
|
|
163
154
|
|
|
164
|
-
@return: A B{C{Vector}} instance or
|
|
165
|
-
C{
|
|
155
|
+
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
156
|
+
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
166
157
|
|
|
167
158
|
@raise AttitudeError: Invalid B{C{x_xyz}}, B{C{y}} or B{C{z}}.
|
|
168
159
|
|
|
160
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
161
|
+
|
|
169
162
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}.
|
|
170
163
|
'''
|
|
171
164
|
try:
|
|
@@ -177,8 +170,9 @@ class Attitude(_NamedBase):
|
|
|
177
170
|
raise AttitudeError(x_xyz=x_xyz, y=y, z=z, cause=x)
|
|
178
171
|
|
|
179
172
|
x, y, z = (fdot(r, *xyz) for r in self.matrix)
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
n, kwds = _name2__(name_Vector_kwds, _or_nameof=self)
|
|
174
|
+
return Vector3Tuple(x, y, z, name=n) if Vector is None else \
|
|
175
|
+
Vector(x, y, z, name=n, **kwds)
|
|
182
176
|
|
|
183
177
|
@property_doc_(' tilt/pitch/elevation from horizontal in C{degrees180}, negative down.')
|
|
184
178
|
def tilt(self):
|
|
@@ -469,29 +463,33 @@ class LocalCartesian(_NamedBase):
|
|
|
469
463
|
'''
|
|
470
464
|
return self._ecef
|
|
471
465
|
|
|
472
|
-
def _ecef2local(self, ecef, Xyz,
|
|
466
|
+
def _ecef2local(self, ecef, Xyz, name_Xyz_kwds):
|
|
473
467
|
'''(INTERNAL) Convert geocentric/geodetic to local, like I{forward}.
|
|
474
468
|
|
|
475
469
|
@arg ecef: Geocentric (and geodetic) (L{Ecef9Tuple}).
|
|
476
470
|
@arg Xyz: An L{XyzLocal}, L{Enu} or L{Ned} I{class} or C{None}.
|
|
477
|
-
@arg
|
|
471
|
+
@arg name_Xyz_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
472
|
+
additional B{C{Xyz}} keyword arguments, ignored if
|
|
473
|
+
C{B{Xyz} is None}.
|
|
478
474
|
|
|
479
|
-
@return: An C{B{Xyz}(x, y, z, ltp, **B{
|
|
480
|
-
C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
475
|
+
@return: An C{B{Xyz}(x, y, z, ltp, **B{name_Xyz_kwds}} instance or
|
|
476
|
+
if C{B{Xyz} is None}, a L{Local9Tuple}C{(x, y, z, lat, lon,
|
|
481
477
|
height, ltp, ecef, M)} with this C{ltp}, B{C{ecef}}
|
|
482
478
|
(L{Ecef9Tuple}) converted to this C{datum} and C{M=None},
|
|
483
479
|
always.
|
|
480
|
+
|
|
481
|
+
@raise TypeError: Invalid B{C{Xyz}} or B{C{name_Xyz_kwds}}.
|
|
484
482
|
'''
|
|
485
483
|
ltp = self
|
|
486
484
|
if ecef.datum != ltp.datum:
|
|
487
485
|
ecef = ecef.toDatum(ltp.datum)
|
|
488
|
-
|
|
486
|
+
n, kwds = _name2__(name_Xyz_kwds, _or_nameof=ecef)
|
|
487
|
+
x, y, z = self.M.rotate(ecef.xyz, *ltp._t0_xyz)
|
|
489
488
|
r = Local9Tuple(x, y, z, ecef.lat, ecef.lon, ecef.height,
|
|
490
|
-
ltp, ecef, None, name=
|
|
489
|
+
ltp, ecef, None, name=n)
|
|
491
490
|
if Xyz:
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
r = r.toXyz(Xyz=Xyz, **Xyz_kwds)
|
|
491
|
+
_xsubclassof(*_XyzLocals4, Xyz=Xyz) # Vector3d
|
|
492
|
+
r = r.toXyz(Xyz=Xyz, name=n, **kwds)
|
|
495
493
|
return r
|
|
496
494
|
|
|
497
495
|
@Property_RO
|
|
@@ -554,7 +552,7 @@ class LocalCartesian(_NamedBase):
|
|
|
554
552
|
'''(INTERNAL) Convert I{local} to geocentric/geodetic, like I{.reverse}.
|
|
555
553
|
|
|
556
554
|
@arg local: Local (L{XyzLocal}, L{Enu}, L{Ned}, L{Aer} or L{Local9Tuple}).
|
|
557
|
-
@kwarg nine:
|
|
555
|
+
@kwarg nine: If C{True}, return a 9-, otherwise a 3-tuple (C{bool}).
|
|
558
556
|
@kwarg M: Include the rotation matrix (C{bool}).
|
|
559
557
|
|
|
560
558
|
@return: A I{geocentric} 3-tuple C{(x, y, z)} or if C{B{nine}=True},
|
|
@@ -1065,8 +1063,17 @@ class ChLVe(_ChLV, LocalCartesian):
|
|
|
1065
1063
|
return t
|
|
1066
1064
|
|
|
1067
1065
|
|
|
1068
|
-
def
|
|
1069
|
-
|
|
1066
|
+
def _fov_2(**fov):
|
|
1067
|
+
# Half a field-of-view angle in C{degrees}.
|
|
1068
|
+
f = Degrees(Error=LocalError, **fov) * _0_5
|
|
1069
|
+
if EPS < f < _90_0:
|
|
1070
|
+
return f
|
|
1071
|
+
t = _invalid_ if f < 0 else _too_(_wide_ if f > EPS else _narrow_)
|
|
1072
|
+
raise LocalError(txt=t, **fov)
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **name_Vector_kwds):
|
|
1076
|
+
'''Convert an attitude pose into a (3-D) direction vector.
|
|
1070
1077
|
|
|
1071
1078
|
@kwarg tilt: Pitch, elevation from horizontal (C{degrees}), negative down
|
|
1072
1079
|
(clockwise rotation along and around the x-axis).
|
|
@@ -1074,17 +1081,28 @@ def tyr3d(tilt=INT0, yaw=INT0, roll=INT0, Vector=Vector3d, **Vector_kwds):
|
|
|
1074
1081
|
(counter-clockwise rotation along and around the z-axis).
|
|
1075
1082
|
@kwarg roll: Roll, bank (C{degrees}), positive to the right and down
|
|
1076
1083
|
(clockwise rotation along and around the y-axis).
|
|
1084
|
+
@kwarg Vector: Class to return the direction vector (C{Cartesian},
|
|
1085
|
+
L{Vector3d} or C{Vector3Tuple}) or C{None}.
|
|
1086
|
+
@kwarg name_Vector_kwds: Optional C{B{name}=NN} (C{str}) and optional,
|
|
1087
|
+
additional B{C{Vector}} keyword arguments, ignored if
|
|
1088
|
+
C{B{Vector} is None}.
|
|
1077
1089
|
|
|
1078
1090
|
@return: A named B{C{Vector}} instance or if B{C{Vector}} is C{None},
|
|
1079
1091
|
a named L{Vector3Tuple}C{(x, y, z)}.
|
|
1080
1092
|
|
|
1093
|
+
@raise AttitudeError: Invalid B{C{tilt}}, B{C{yaw}} or B{C{roll}}.
|
|
1094
|
+
|
|
1095
|
+
@raise TypeError: Invalid B{C{Vector}} or B{C{name_Vector_kwds}}.
|
|
1096
|
+
|
|
1081
1097
|
@see: U{Yaw, pitch, and roll rotations<http://MSL.CS.UIUC.edu/planning/node102.html>}
|
|
1082
|
-
and function L{pygeodesy.hartzell} argument C{los}.
|
|
1098
|
+
and function L{pygeodesy.hartzell} argument C{los}, Line-Of-Sight.
|
|
1083
1099
|
'''
|
|
1084
1100
|
d = Attitude4Tuple(_0_0, tilt, yaw, roll).tyr3d
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1101
|
+
if Vector is not type(d):
|
|
1102
|
+
n, kwds = _name2__(name_Vector_kwds, name__=tyr3d)
|
|
1103
|
+
d = Vector3Tuple(d.x, d.y, d.z, name=n) if Vector is None else \
|
|
1104
|
+
Vector(d.x, d.y, d.z, name=n, **kwds)
|
|
1105
|
+
return d
|
|
1088
1106
|
|
|
1089
1107
|
|
|
1090
1108
|
def _xLtp(ltp, *dflt):
|