pygeodesy 24.8.4__py2.py3-none-any.whl → 24.9.9__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.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/METADATA +17 -16
- PyGeodesy-24.9.9.dist-info/RECORD +118 -0
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/WHEEL +1 -1
- pygeodesy/__init__.py +23 -23
- pygeodesy/__main__.py +46 -47
- pygeodesy/auxilats/_CX_4.py +104 -181
- pygeodesy/auxilats/_CX_6.py +152 -277
- pygeodesy/auxilats/_CX_8.py +211 -438
- pygeodesy/auxilats/_CX_Rs.py +222 -0
- pygeodesy/auxilats/__init__.py +2 -2
- pygeodesy/auxilats/__main__.py +30 -38
- pygeodesy/auxilats/auxDST.py +2 -2
- pygeodesy/auxilats/auxLat.py +28 -36
- pygeodesy/auxilats/auxily.py +30 -50
- pygeodesy/basics.py +18 -7
- pygeodesy/booleans.py +10 -11
- pygeodesy/cartesianBase.py +5 -5
- pygeodesy/constants.py +35 -34
- pygeodesy/ellipsoidalBase.py +18 -15
- pygeodesy/ellipsoidalExact.py +2 -2
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +2 -2
- pygeodesy/ellipsoidalNvector.py +2 -2
- pygeodesy/ellipsoidalVincenty.py +7 -6
- pygeodesy/elliptic.py +154 -88
- pygeodesy/epsg.py +3 -3
- pygeodesy/etm.py +71 -59
- pygeodesy/fmath.py +99 -90
- pygeodesy/fsums.py +201 -14
- pygeodesy/gars.py +9 -8
- pygeodesy/geodesici.py +6 -5
- pygeodesy/geodesicx/_C4_24.py +1 -3
- pygeodesy/geodesicx/_C4_27.py +1 -3
- pygeodesy/geodesicx/_C4_30.py +1 -3
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +44 -46
- pygeodesy/geodesicx/gx.py +3 -3
- pygeodesy/geodesicx/gxarea.py +5 -5
- pygeodesy/geodesicx/gxbases.py +32 -18
- pygeodesy/geodsolve.py +3 -3
- pygeodesy/geohash.py +18 -11
- pygeodesy/geoids.py +293 -315
- pygeodesy/heights.py +150 -158
- pygeodesy/internals.py +70 -9
- pygeodesy/interns.py +4 -4
- pygeodesy/karney.py +83 -60
- pygeodesy/ktm.py +4 -4
- pygeodesy/latlonBase.py +13 -7
- pygeodesy/lazily.py +13 -8
- pygeodesy/ltp.py +5 -6
- pygeodesy/ltpTuples.py +7 -1
- pygeodesy/mgrs.py +47 -42
- pygeodesy/named.py +8 -4
- pygeodesy/namedTuples.py +14 -1
- pygeodesy/osgr.py +7 -7
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +7 -6
- pygeodesy/resections.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +42 -60
- pygeodesy/rhumb/solve.py +3 -3
- pygeodesy/simplify.py +10 -10
- pygeodesy/sphericalBase.py +3 -3
- pygeodesy/sphericalTrigonometry.py +2 -2
- pygeodesy/streprs.py +3 -3
- pygeodesy/triaxials.py +207 -201
- pygeodesy/units.py +3 -3
- pygeodesy/unitsBase.py +4 -4
- pygeodesy/utmupsBase.py +3 -3
- pygeodesy/vector2d.py +158 -51
- pygeodesy/vector3d.py +13 -52
- pygeodesy/vector3dBase.py +81 -63
- pygeodesy/webmercator.py +3 -3
- pygeodesy/wgrs.py +20 -22
- PyGeodesy-24.8.4.dist-info/RECORD +0 -117
- {PyGeodesy-24.8.4.dist-info → PyGeodesy-24.9.9.dist-info}/top_level.txt +0 -0
pygeodesy/interns.py
CHANGED
|
@@ -184,7 +184,6 @@ _concentric_ = 'concentric' # PYCHOK OK
|
|
|
184
184
|
_convergence_ = _Prefix('convergence') # PYCHOK OK
|
|
185
185
|
_conversion_ = 'conversion' # PYCHOK OK
|
|
186
186
|
_convex_ = 'convex' # PYCHOK OK
|
|
187
|
-
_cubic_ = 'cubic' # PYCHOK OK
|
|
188
187
|
_d_ = 'd' # PYCHOK OK
|
|
189
188
|
_D_ = 'D' # PYCHOK OK
|
|
190
189
|
_DASH_ = Str_('-') # PYCHOK == _MINUS_
|
|
@@ -201,6 +200,7 @@ _distant_ = _Prefix('distant') # PYCHOK OK
|
|
|
201
200
|
_doesn_t_exist_ = "doesn't exist" # PYCHOK OK
|
|
202
201
|
_DOT_ = Str_('.') # PYCHOK OK
|
|
203
202
|
_dunder_name_ = '__name__' # PYCHOK _DUNDER_(NN, _name_, NN)
|
|
203
|
+
_duplicate_ = 'duplicate' # PYCHOK OK
|
|
204
204
|
_e_ = 'e' # PYCHOK OK
|
|
205
205
|
_E_ = 'E' # PYCHOK OK
|
|
206
206
|
_earth_ = 'earth' # PYCHOK OK
|
|
@@ -250,6 +250,7 @@ _inside_ = 'inside' # PYCHOK OK
|
|
|
250
250
|
_insufficient_ = 'insufficient' # PYCHOK OK
|
|
251
251
|
_intersection_ = 'intersection' # PYCHOK OK
|
|
252
252
|
_Intl1924_ = 'Intl1924' # PYCHOK OK
|
|
253
|
+
_INV_ = 'INV' # PYCHOK INValid
|
|
253
254
|
_invalid_ = 'invalid' # PYCHOK OK
|
|
254
255
|
_invokation_ = 'invokation' # PYCHOK OK
|
|
255
256
|
_j_ = 'j' # PYCHOK OK
|
|
@@ -270,7 +271,6 @@ _LCURLY_ = '{' # PYCHOK LBRACE
|
|
|
270
271
|
_len_ = 'len' # PYCHOK OK
|
|
271
272
|
_limit_ = 'limit' # PYCHOK OK
|
|
272
273
|
_line_ = 'line' # PYCHOK OK
|
|
273
|
-
_linear_ = 'linear' # PYCHOK OK
|
|
274
274
|
_LPAREN_ = '(' # PYCHOK OK
|
|
275
275
|
_lon_ = 'lon' # PYCHOK OK
|
|
276
276
|
_lon0_ = 'lon0' # PYCHOK OK
|
|
@@ -348,7 +348,7 @@ _Python_ = _Python_('Python') # PYCHOK singleton
|
|
|
348
348
|
_python_ = 'python' # PYCHOK OK
|
|
349
349
|
_QUOTE1_ = "'" # PYCHOK OK
|
|
350
350
|
_QUOTE2_ = '"' # PYCHOK OK
|
|
351
|
-
|
|
351
|
+
_QUOTE3_ = "'''" # PYCHOK OK
|
|
352
352
|
# _QUOTE6_ = '"""' # PYCHOK OK
|
|
353
353
|
_R_ = 'R' # PYCHOK OK
|
|
354
354
|
_radians_ = 'radians' # PYCHOK OK
|
|
@@ -441,7 +441,7 @@ _LR_PAIRS = {_LANGLE_: _RANGLE_,
|
|
|
441
441
|
|
|
442
442
|
__all__ = (_NN_, # NOT MISSING!
|
|
443
443
|
Str_.__name__) # classes
|
|
444
|
-
__version__ = '24.
|
|
444
|
+
__version__ = '24.08.30'
|
|
445
445
|
|
|
446
446
|
if __name__ == '__main__':
|
|
447
447
|
|
pygeodesy/karney.py
CHANGED
|
@@ -10,7 +10,9 @@ C{attribute} name.
|
|
|
10
10
|
|
|
11
11
|
With env variable C{PYGEODESY_GEOGRAPHICLIB} left undefined or set to C{"2"}, modules L{geodesicw},
|
|
12
12
|
L{geodesicx} and this module will use U{GeographicLib 2.0+<https://GeographicLib.SourceForge.io/C++/doc/>}
|
|
13
|
-
and newer transcoding, otherwise C{1.52} or older.
|
|
13
|
+
and newer transcoding, otherwise C{1.52} or older. Set C{PYGEODESY_GEOGRAPHICLIB=2.4} to default to the
|
|
14
|
+
C{Jacobi amplitude} instead of C{Bulirsch}' function in methods L{ExactTransverseMercator.forward
|
|
15
|
+
<pygeodesy.ExactTransverseMercator.forward>} and L{reverse <pygeodesy.ExactTransverseMercator.reverse>}.
|
|
14
16
|
|
|
15
17
|
Karney-based functionality
|
|
16
18
|
==========================
|
|
@@ -145,8 +147,8 @@ from pygeodesy.basics import _copysign, isint, neg, unsigned0, _xgeographiclib,
|
|
|
145
147
|
_zip, _version_info
|
|
146
148
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
|
|
147
149
|
_1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
148
|
-
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds
|
|
149
|
-
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
150
|
+
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds
|
|
151
|
+
from pygeodesy.fmath import cbrt, fremainder, norm2 # Fhorner, Fsum
|
|
150
152
|
# from pygeodesy.internals import _version_info # from .basics
|
|
151
153
|
from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
152
154
|
_composite_, _lat1_, _lat2_, _lon1_, _lon2_, \
|
|
@@ -154,7 +156,8 @@ from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
|
154
156
|
_UNDER_, _X_, _BAR_ # PYCHOK used!
|
|
155
157
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
156
158
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
157
|
-
from pygeodesy.props import deprecated_method, Property_RO,
|
|
159
|
+
from pygeodesy.props import deprecated_method, Property_RO, property_RO, \
|
|
160
|
+
property_ROnce
|
|
158
161
|
from pygeodesy.units import Azimuth as _Azi, Degrees as _Deg, Lat, Lon, \
|
|
159
162
|
Meter as _M, Meter2 as _M2, Number_
|
|
160
163
|
from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
@@ -162,9 +165,11 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
162
165
|
# from math import fabs # from .utily
|
|
163
166
|
|
|
164
167
|
__all__ = _ALL_LAZY.karney
|
|
165
|
-
__version__ = '24.
|
|
168
|
+
__version__ = '24.09.10'
|
|
166
169
|
|
|
167
|
-
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_)
|
|
170
|
+
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_)
|
|
171
|
+
_K_2_4 = _K_2_0 == '2.4'
|
|
172
|
+
_K_2_0 = _K_2_0 == _2_ or _K_2_4
|
|
168
173
|
_perimeter_ = 'perimeter'
|
|
169
174
|
|
|
170
175
|
|
|
@@ -285,7 +290,7 @@ class Caps(object):
|
|
|
285
290
|
|
|
286
291
|
Caps = Caps() # PYCHOK singleton
|
|
287
292
|
'''I{Enum}-style masks to be bit-C{or}'ed to specify geodesic or
|
|
288
|
-
rhumb capabilities (C{caps}) and
|
|
293
|
+
rhumb capabilities (C{caps}) and results (C{outmask}).
|
|
289
294
|
|
|
290
295
|
C{AREA} - compute area C{S12},
|
|
291
296
|
|
|
@@ -569,6 +574,11 @@ class _kWrapped(object): # in .geodesicw
|
|
|
569
574
|
M = None
|
|
570
575
|
return M
|
|
571
576
|
|
|
577
|
+
@property_RO
|
|
578
|
+
def Math_K_2(self):
|
|
579
|
+
return ('_K_2_4' if _K_2_4 else
|
|
580
|
+
('_K_2_0' if _K_2_0 else '_K_1_0')) if self.Math else NN
|
|
581
|
+
|
|
572
582
|
_wrapped = _kWrapped() # PYCHOK singleton, .datum, .test/base.py
|
|
573
583
|
|
|
574
584
|
|
|
@@ -805,25 +815,44 @@ def _polygon(geodesic, points, closed, line, wrap):
|
|
|
805
815
|
return gP.Compute(False, True)[1 if line else 2]
|
|
806
816
|
|
|
807
817
|
|
|
818
|
+
try:
|
|
819
|
+
from math import fma as _fma # since 3.13
|
|
820
|
+
|
|
821
|
+
def _poly_fma(x, s, *cs):
|
|
822
|
+
for c in cs:
|
|
823
|
+
s = _fma(s, x, c)
|
|
824
|
+
return s
|
|
825
|
+
|
|
826
|
+
except ImportError: # Python 3.12-
|
|
827
|
+
|
|
828
|
+
def _poly_fma(x, s, *cs): # PYCHOK redef
|
|
829
|
+
t = _0_0
|
|
830
|
+
for c in cs:
|
|
831
|
+
s, t, _ = _sum3(s * x, t * x, c)
|
|
832
|
+
return s + t
|
|
833
|
+
|
|
834
|
+
# def _poly_fma(x, *cs):
|
|
835
|
+
# S = Fhorner(x, *cs, incx=False)
|
|
836
|
+
# return float(S)
|
|
837
|
+
|
|
838
|
+
# def _poly_fma(x, s, *cs): # scalar x, s, cs
|
|
839
|
+
# S = Fsum(s)._fma_scalar(None, x, *cs)
|
|
840
|
+
# return float(S)
|
|
841
|
+
|
|
808
842
|
def _polynomial(x, cs, i, j): # PYCHOK shared
|
|
809
843
|
'''(INTERNAL) Like C++ C{GeographicLib.Math.hpp.polyval} but with a
|
|
810
|
-
|
|
844
|
+
signature and cascaded summation different from C{karney._sum3}.
|
|
811
845
|
|
|
812
|
-
@return: M{sum(
|
|
846
|
+
@return: M{sum(x**(j - k - 1) * cs[k] for k in range(i, j)}
|
|
813
847
|
'''
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
s = cs[i]
|
|
823
|
-
i += 1
|
|
824
|
-
if x and i < j:
|
|
825
|
-
s, _ = _sum2_(s, _0_0, x=x, *cs[i:j])
|
|
826
|
-
return s # + t
|
|
848
|
+
if (i + 1) < j <= len(cs): # load _Rtuple._tuple
|
|
849
|
+
try:
|
|
850
|
+
r = _wrapped.Math.polyval(j - i - 1, cs, i, x)
|
|
851
|
+
except AttributeError:
|
|
852
|
+
r = _poly_fma(x, *cs[i:j])
|
|
853
|
+
else:
|
|
854
|
+
r = cs[i]
|
|
855
|
+
return float(r)
|
|
827
856
|
|
|
828
857
|
|
|
829
858
|
def _remainder(x, y):
|
|
@@ -875,67 +904,60 @@ def _sincos2de(deg, t):
|
|
|
875
904
|
return sincos2d(deg, adeg=t)
|
|
876
905
|
|
|
877
906
|
|
|
878
|
-
def _sum2(
|
|
907
|
+
def _sum2(a, b): # mimick geomath.Math.sum, actually sum2
|
|
879
908
|
'''Error-free summation like C{geomath.Math.sum}.
|
|
880
909
|
|
|
881
|
-
@return: 2-Tuple C{(B{
|
|
910
|
+
@return: 2-Tuple C{(B{a} + B{b}, residual)}.
|
|
882
911
|
|
|
883
|
-
@note: The C{residual} can be the same as B{C{
|
|
912
|
+
@note: The C{residual} can be the same as B{C{a}} or B{C{b}}.
|
|
884
913
|
|
|
885
|
-
@see: U{
|
|
914
|
+
@see: U{TwoSum<https://accurate-algorithms.readthedocs.io/en/latest/ch04summation.html>}
|
|
915
|
+
and I{Knuth}'s U{Algorithm 3.1<https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}.
|
|
886
916
|
'''
|
|
887
917
|
try:
|
|
888
|
-
return _wrapped.Math.sum(
|
|
918
|
+
return _wrapped.Math.sum(a, b)
|
|
889
919
|
except AttributeError:
|
|
890
|
-
s = u + v
|
|
891
|
-
r = s - v
|
|
892
|
-
t = s - r
|
|
893
920
|
# if Algorithm_3_1:
|
|
894
|
-
|
|
921
|
+
s = a + b
|
|
922
|
+
r = s - b
|
|
923
|
+
t = s - r
|
|
895
924
|
# elif C_CPP: # Math::sum C/C++
|
|
896
|
-
# r -=
|
|
897
|
-
# t -= v
|
|
898
|
-
# t += r
|
|
899
|
-
# t = -t
|
|
925
|
+
# r -= a; t -= b; t += r; t = -t
|
|
900
926
|
# else:
|
|
901
|
-
t = (
|
|
927
|
+
t = (a - r) + (b - t)
|
|
928
|
+
# assert fabs(s) >= fabs(t)
|
|
902
929
|
return s, t
|
|
903
930
|
|
|
904
931
|
|
|
905
|
-
def
|
|
906
|
-
'''Accumulate any B{C{
|
|
907
|
-
|
|
908
|
-
@kwarg x: Optional polynomial C{B{x}=1} (C{scalar}).
|
|
932
|
+
def _sum3(s, t, *xs):
|
|
933
|
+
'''Accumulate any B{C{xs}} into a previous C{_sum2(s, t)}.
|
|
909
934
|
|
|
910
|
-
@return:
|
|
935
|
+
@return: 3-Tuple C{(s, t, n)} where C{s} is the sum of B{s}, B{t} and all
|
|
936
|
+
B{xs}, C{t} the residual and C{n} the number of zero C{xs}.
|
|
911
937
|
|
|
912
938
|
@see: I{Karney's} C++ U{Accumulator<https://GeographicLib.SourceForge.io/
|
|
913
939
|
C++/doc/Accumulator_8hpp_source.html>} comments for more details and
|
|
914
940
|
function C{_sum2} above.
|
|
915
941
|
|
|
916
|
-
@note:
|
|
942
|
+
@note: Not "error-free", see C{pygeodesy.test/testKarney.py}.
|
|
917
943
|
'''
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
for v in vs:
|
|
923
|
-
if p:
|
|
924
|
-
s *= x
|
|
925
|
-
t *= x
|
|
926
|
-
if v:
|
|
927
|
-
t, u = _s2(t, v) # start at the least-
|
|
944
|
+
z = 0
|
|
945
|
+
for x in xs:
|
|
946
|
+
if x:
|
|
947
|
+
t, r = _sum2(t, x) # start at the least-
|
|
928
948
|
if s:
|
|
929
|
-
s, t =
|
|
949
|
+
s, t = _sum2(s, t) # -significant end
|
|
930
950
|
if s:
|
|
931
|
-
t +=
|
|
932
|
-
# elif t: # s == 0 implies t == 0
|
|
933
|
-
# raise _AssertionError(t=t, txt_not_=_0_)
|
|
951
|
+
t += r # accumulate r into t
|
|
934
952
|
else:
|
|
935
|
-
|
|
953
|
+
# assert t == 0 # s == 0 implies t == 0
|
|
954
|
+
s = unsigned0(r) # result is r, t = 0
|
|
936
955
|
else:
|
|
937
|
-
s, t =
|
|
938
|
-
|
|
956
|
+
s, t = unsigned0(t), r
|
|
957
|
+
else:
|
|
958
|
+
z += 1
|
|
959
|
+
# assert fabs(s) >= fabs(t)
|
|
960
|
+
return s, t, z
|
|
939
961
|
|
|
940
962
|
|
|
941
963
|
def _tand(x):
|
|
@@ -955,7 +977,8 @@ def _unroll2(lon1, lon2, wrap=False): # see .ellipsoidalBaseDI._intersects2
|
|
|
955
977
|
'''
|
|
956
978
|
if wrap:
|
|
957
979
|
d, t = _diff182(lon1, lon2)
|
|
958
|
-
lon2, _ =
|
|
980
|
+
lon2, t, _ = _sum3(d, t, lon1) # (lon1 + d) + t
|
|
981
|
+
lon2 += t
|
|
959
982
|
else:
|
|
960
983
|
lon2 = _norm180(lon2)
|
|
961
984
|
return (lon2 - lon1), lon2
|
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.08.31'
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class KTMError(_ValueError):
|
|
@@ -505,11 +505,11 @@ def _Xs(_Coeffs, m, E, RA=False): # in .rhumb.ekx
|
|
|
505
505
|
# constant, it cancels when evaluating a definite
|
|
506
506
|
# integral. Don't bother computing it, it is unused
|
|
507
507
|
# in C{_Cyxgk4} above and C{rhumb.ekx._sincosSeries}.
|
|
508
|
-
|
|
509
|
-
|
|
508
|
+
i = (m + 2) if RA else 0
|
|
509
|
+
_p = _polynomial
|
|
510
510
|
for r in _reverange(m): # [m-1 ... 0]
|
|
511
511
|
j = i + r + 1
|
|
512
|
-
|
|
512
|
+
X.append(_p(n, Cs, i, j) * n_ / Cs[j])
|
|
513
513
|
i = j + 1
|
|
514
514
|
n_ *= n
|
|
515
515
|
X = tuple(X)
|
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.
|
|
57
|
+
__version__ = '24.08.18'
|
|
58
58
|
|
|
59
59
|
_formy = _MODS.into(formy=__name__)
|
|
60
60
|
|
|
@@ -247,7 +247,7 @@ class LatLonBase(_NamedBase):
|
|
|
247
247
|
|
|
248
248
|
@arg point2: Second point (C{LatLon}).
|
|
249
249
|
@arg point3: Third point (C{LatLon}).
|
|
250
|
-
@kwarg circum: If C{True} return the C{circumradius} and C{circumcenter},
|
|
250
|
+
@kwarg circum: If C{True}, return the C{circumradius} and C{circumcenter},
|
|
251
251
|
always, ignoring the I{Meeus}' Type I case (C{bool}).
|
|
252
252
|
@kwarg eps: Tolerance for function L{pygeodesy.trilaterate3d2}.
|
|
253
253
|
@kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and optional keyword
|
|
@@ -699,9 +699,9 @@ class LatLonBase(_NamedBase):
|
|
|
699
699
|
I{overriding} this datum (L{Datum}, L{Ellipsoid},
|
|
700
700
|
L{Ellipsoid2}, L{a_f2Tuple}, L{Triaxial}, L{Triaxial_},
|
|
701
701
|
L{JacobiConformal} or C{meter}, conventionally).
|
|
702
|
-
@kwarg normal: If C{True} the projection is the normal to this
|
|
703
|
-
|
|
704
|
-
|
|
702
|
+
@kwarg normal: If C{True}, the projection is the normal to this ellipsoid's
|
|
703
|
+
surface, otherwise the intersection of the I{radial} line to
|
|
704
|
+
this ellipsoid's center (C{bool}).
|
|
705
705
|
@kwarg LatLon: Optional class to return the projection, height and
|
|
706
706
|
datum (C{LatLon}) or C{None}.
|
|
707
707
|
@kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword arguments,
|
|
@@ -1483,8 +1483,8 @@ class LatLonBase(_NamedBase):
|
|
|
1483
1483
|
'''Get this point I{normalized} to C{abs(lat) <= 90}
|
|
1484
1484
|
and C{abs(lon) <= 180}.
|
|
1485
1485
|
|
|
1486
|
-
@kwarg deep: If C{True} make a deep, otherwise a
|
|
1487
|
-
|
|
1486
|
+
@kwarg deep: If C{True}, make a deep, otherwise a shallow
|
|
1487
|
+
copy (C{bool}).
|
|
1488
1488
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1489
1489
|
|
|
1490
1490
|
@return: A copy of this point, I{normalized} (C{LatLon}),
|
|
@@ -1650,6 +1650,12 @@ class LatLonBase(_NamedBase):
|
|
|
1650
1650
|
'''
|
|
1651
1651
|
return self._ecef9.xyz
|
|
1652
1652
|
|
|
1653
|
+
@property_RO
|
|
1654
|
+
def xyz3(self):
|
|
1655
|
+
'''Get the I{geocentric} C{(x, y, z)} coordinates as C{3-tuple}.
|
|
1656
|
+
'''
|
|
1657
|
+
return tuple(self.xyz)
|
|
1658
|
+
|
|
1653
1659
|
@Property_RO
|
|
1654
1660
|
def xyzh(self):
|
|
1655
1661
|
'''Get the I{geocentric} C{(x, y, z)} coordinates and height (L{Vector4Tuple}C{(x, y, z, h)})
|
pygeodesy/lazily.py
CHANGED
|
@@ -255,7 +255,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
255
255
|
fmath=_i('Fdot', 'Fhorner', 'Fhypot', 'Fpolynomial', 'Fpowers', 'Fcbrt', 'Froot', 'Fsqrt',
|
|
256
256
|
'bqrt', 'cbrt', 'cbrt2', 'euclid', 'euclid_',
|
|
257
257
|
'facos1', 'fasin1', 'fatan', 'fatan1', 'fatan2', 'favg',
|
|
258
|
-
'fdot', 'fdot3', 'fmean', 'fmean_', 'fhorner', 'fidw', 'fpolynomial',
|
|
258
|
+
'fdot', 'fdot3', 'fma', 'fmean', 'fmean_', 'fhorner', 'fidw', 'fpolynomial',
|
|
259
259
|
'fpowers', 'fprod', 'frandoms', 'frange', 'freduce', 'fremainder',
|
|
260
260
|
'hypot', 'hypot_', 'hypot1', 'hypot2', 'hypot2_',
|
|
261
261
|
'norm2', 'norm_', 'sqrt0', 'sqrt3', 'sqrt_a', 'zcrt', 'zqrt'),
|
|
@@ -280,7 +280,7 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
280
280
|
'FrechetVincentys', 'Frechet6Tuple',
|
|
281
281
|
'frechet_'),
|
|
282
282
|
fstats=_i('Fcook', 'Flinear', 'Fwelford'),
|
|
283
|
-
fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
|
|
283
|
+
fsums=_i('Fsum', 'Fsum2product', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
|
|
284
284
|
'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
|
|
285
285
|
gars=_i('Garef', 'GARSError'),
|
|
286
286
|
geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Intersect7Tuple',
|
|
@@ -395,10 +395,10 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
395
395
|
utmups=_i('UtmUps', 'UTMUPSError', 'parseUTMUPS5', 'toUtmUps8',
|
|
396
396
|
'utmupsValidate', 'utmupsValidateOK', 'utmupsZoneBand5'),
|
|
397
397
|
utmupsBase=_i(), # module only
|
|
398
|
-
vector2d=_i('Circin6Tuple', 'Circum3Tuple', 'Circum4Tuple', 'Meeus2Tuple', 'Radii11Tuple', 'Soddy4Tuple',
|
|
399
|
-
'circin6', 'circum3', 'circum4_', 'meeus2', 'radii11', 'soddy4'),
|
|
398
|
+
vector2d=_i('Circin6Tuple', 'Circum3Tuple', 'Circum4Tuple', 'Meeus2Tuple', 'Radii11Tuple', 'Soddy4Tuple', 'Triaxum5Tuple',
|
|
399
|
+
'circin6', 'circum3', 'circum4', 'circum4_', 'meeus2', 'radii11', 'soddy4', 'triaxum5', 'trilaterate2d2'),
|
|
400
400
|
vector3d=_i('Vector3d', 'intersection3d3', 'iscolinearWith', 'nearestOn', 'nearestOn6', 'parse3d',
|
|
401
|
-
'
|
|
401
|
+
'trilaterate3d2'),
|
|
402
402
|
vector3dBase=_i(), # module only
|
|
403
403
|
webmercator=_i('Wm', 'WebMercatorError', 'parseWM', 'toWm', 'EasNorRadius3Tuple'),
|
|
404
404
|
wgrs=_i('Georef', 'WGRSError'),)
|
|
@@ -416,8 +416,8 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
416
416
|
deprecated_datum=_i('Curvature2Tuple', 'Datum', 'Ellipsoid', 'Transform', # assert
|
|
417
417
|
'Datums', 'Ellipsoids', 'Transforms',
|
|
418
418
|
'R_FM', 'R_KM', 'R_M', 'R_MA', 'R_MB', 'R_NM', 'R_SM', 'R_VM'),
|
|
419
|
-
deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ...
|
|
420
|
-
'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ...
|
|
419
|
+
deprecated_functions=_i('anStr', 'areaof', 'atand', 'bounds', # most of the DEPRECATED functions, except ellipsoidal ...
|
|
420
|
+
'clipCS3', 'clipDMS', 'clipStr', 'collins', 'copysign', # ... and spherical flavors
|
|
421
421
|
'decodeEPSG2', 'encodeEPSG', 'enStr2', 'equirectangular_', 'equirectangular3',
|
|
422
422
|
'excessAbc', 'excessGirard', 'excessLHuilier',
|
|
423
423
|
'false2f', 'falsed2f', 'float0', 'fStr', 'fStrzs', 'hypot3',
|
|
@@ -486,6 +486,11 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
486
486
|
except KeyError:
|
|
487
487
|
return _getmodule(name, parent)
|
|
488
488
|
|
|
489
|
+
def imported(self, name):
|
|
490
|
+
'''Return module or package C{name} if already imported.
|
|
491
|
+
'''
|
|
492
|
+
return _sys.modules.get(name, None)
|
|
493
|
+
|
|
489
494
|
def into(self, **mod_dunder_name_):
|
|
490
495
|
'''Lazily import module C{mod} into module C{_dunder_name_}
|
|
491
496
|
and set C{_dunder_name_._mod} to module C{mod}, I{once}.
|
|
@@ -521,7 +526,7 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
521
526
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
522
527
|
|
|
523
528
|
__all__ = _ALL_LAZY.lazily
|
|
524
|
-
__version__ = '24.
|
|
529
|
+
__version__ = '24.09.09'
|
|
525
530
|
|
|
526
531
|
|
|
527
532
|
def _ALL_OTHER(*objs):
|
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.
|
|
47
|
+
__version__ = '24.08.18'
|
|
48
48
|
|
|
49
49
|
_height0_ = _height_ + _0_
|
|
50
50
|
_narrow_ = 'narrow'
|
|
@@ -165,7 +165,7 @@ class Attitude(_NamedBase):
|
|
|
165
165
|
'''
|
|
166
166
|
try:
|
|
167
167
|
try:
|
|
168
|
-
xyz = map2(float, x_xyz.
|
|
168
|
+
xyz = map2(float, x_xyz.xyz3)
|
|
169
169
|
except AttributeError:
|
|
170
170
|
xyz = map1(float, x_xyz, y, z)
|
|
171
171
|
except (TypeError, ValueError) as x:
|
|
@@ -876,7 +876,7 @@ class ChLV(_ChLV, Ltp):
|
|
|
876
876
|
|
|
877
877
|
@arg Y: Unfalsed I{Swiss Y} easting (C{meter}).
|
|
878
878
|
@arg X: Unfalsed I{Swiss X} northing (C{meter}).
|
|
879
|
-
@kwarg LV95: If C{True} add C{LV95} falsing, if C{False} add
|
|
879
|
+
@kwarg LV95: If C{True}, add C{LV95} falsing, if C{False} add
|
|
880
880
|
C{LV03} falsing, otherwise leave unfalsed.
|
|
881
881
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
882
882
|
|
|
@@ -928,9 +928,8 @@ class ChLV(_ChLV, Ltp):
|
|
|
928
928
|
|
|
929
929
|
@arg e: Falsed I{Swiss E_LV95} or I{y_LV03} easting (C{meter}).
|
|
930
930
|
@arg n: Falsed I{Swiss N_LV95} or I{x_LV03} northing (C{meter}).
|
|
931
|
-
@kwarg LV95: If C{True} remove I{LV95} falsing, if C{False} remove
|
|
932
|
-
I{LV03} falsing, otherwise use method C{isLV95(B{e},
|
|
933
|
-
B{n})}.
|
|
931
|
+
@kwarg LV95: If C{True}, remove I{LV95} falsing, if C{False} remove
|
|
932
|
+
I{LV03} falsing, otherwise use method C{isLV95(B{e}, B{n})}.
|
|
934
933
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
935
934
|
|
|
936
935
|
@return: A L{ChLVYX2Tuple}C{(Y, X)} with the unfalsed B{C{e}}
|
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.
|
|
39
|
+
__version__ = '24.08.18'
|
|
40
40
|
|
|
41
41
|
_aer_ = 'aer'
|
|
42
42
|
_alt_ = 'alt'
|
|
@@ -189,6 +189,12 @@ class _AbcBase(_NamedBase):
|
|
|
189
189
|
'''
|
|
190
190
|
return Vector3Tuple(self.x, self.y, self.z, name=self.name) # like Ecef9Tuple.xyz, Local6tuple.xyz
|
|
191
191
|
|
|
192
|
+
@property_RO
|
|
193
|
+
def xyz3(self):
|
|
194
|
+
'''Get the I{local} C{(X, Y, Z)} coordinates as C{3-tuple}.
|
|
195
|
+
'''
|
|
196
|
+
return tuple(self.xyz)
|
|
197
|
+
|
|
192
198
|
@property_RO
|
|
193
199
|
def xyz4(self): # PYCHOK no cover
|
|
194
200
|
'''I{Must be overloaded}.'''
|
pygeodesy/mgrs.py
CHANGED
|
@@ -43,7 +43,7 @@ from pygeodesy.errors import _AssertionError, MGRSError, _parseX, \
|
|
|
43
43
|
from pygeodesy.interns import NN, _0_, _A_, _AtoZnoIO_, _band_, _B_, \
|
|
44
44
|
_COMMASPACE_, _datum_, _easting_, _invalid_, \
|
|
45
45
|
_northing_, _SPACE_, _W_, _Y_, _Z_, _zone_
|
|
46
|
-
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
46
|
+
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
47
47
|
from pygeodesy.named import _name2__, _NamedBase, _NamedTuple, _Pass
|
|
48
48
|
from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple
|
|
49
49
|
from pygeodesy.props import deprecated_property_RO, property_RO, Property_RO
|
|
@@ -55,7 +55,7 @@ from pygeodesy.utm import toUtm8, _to3zBlat, Utm, _UTM_ZONE_MAX, _UTM_ZONE_MIN
|
|
|
55
55
|
# from pygeodesy.utmupsBase import _UTM_ZONE_MAX, _UTM_ZONE_MIN # from .utm
|
|
56
56
|
|
|
57
57
|
__all__ = _ALL_LAZY.mgrs
|
|
58
|
-
__version__ = '24.
|
|
58
|
+
__version__ = '24.09.04'
|
|
59
59
|
|
|
60
60
|
_AN_ = 'AN' # default south pole grid tile and band B
|
|
61
61
|
_AtoPx_ = _AtoZnoIO_.tillP
|
|
@@ -652,51 +652,56 @@ def _um100km2(m):
|
|
|
652
652
|
|
|
653
653
|
if __name__ == '__main__':
|
|
654
654
|
|
|
655
|
-
|
|
656
|
-
# from pygeodesy.internals import printf # from .lazily
|
|
657
|
-
from pygeodesy.lazily import _getenv, printf
|
|
655
|
+
def _main():
|
|
658
656
|
|
|
659
|
-
|
|
660
|
-
|
|
657
|
+
from pygeodesy.ellipsoidalVincenty import fabs, LatLon
|
|
658
|
+
from pygeodesy.internals import _fper, printf
|
|
659
|
+
from pygeodesy.lazily import _getenv, _PYGEODESY_GEOCONVERT_
|
|
661
660
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if _access(_GeoConvert, _X_OK):
|
|
665
|
-
GC_m = _GeoConvert, '-m' # -m converts latlon to MGRS
|
|
666
|
-
printf(' using: %s ...', _SPACE_.join(GC_m))
|
|
667
|
-
from pygeodesy.solveBase import _popen2
|
|
668
|
-
else:
|
|
669
|
-
GC_m = _popen2 = None
|
|
661
|
+
# from math import fabs # from .ellipsoidalVincenty
|
|
662
|
+
from os import access as _access, linesep as _NL, X_OK as _X_OK
|
|
670
663
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
664
|
+
# <https://GeographicLib.sourceforge.io/C++/doc/GeoConvert.1.html>
|
|
665
|
+
_GeoConvert = _getenv(_PYGEODESY_GEOCONVERT_, '/opt/local/bin/GeoConvert')
|
|
666
|
+
if _access(_GeoConvert, _X_OK):
|
|
667
|
+
GC_m = _GeoConvert, '-m' # -m converts latlon to MGRS
|
|
668
|
+
printf(' using: %s ...', _SPACE_.join(GC_m))
|
|
669
|
+
from pygeodesy.solveBase import _popen2
|
|
670
|
+
else:
|
|
671
|
+
GC_m = _popen2 = None
|
|
672
|
+
|
|
673
|
+
e = n = 0
|
|
674
|
+
try:
|
|
675
|
+
for lat in range(-90, 91, 1):
|
|
676
|
+
printf('%6s: lat %s ...', n, lat, end=NN, flush=True)
|
|
677
|
+
nl = _NL
|
|
678
|
+
for lon in range(-180, 181, 1):
|
|
679
|
+
m = LatLon(lat, lon).toMgrs()
|
|
680
|
+
if _popen2:
|
|
681
|
+
t = '%s %s' % (lat, lon)
|
|
682
|
+
g = _popen2(GC_m, stdin=t)[1]
|
|
683
|
+
t = m.toStr() # sep=NN
|
|
684
|
+
if t != g:
|
|
685
|
+
e += 1
|
|
686
|
+
printf('%s%6s: %s: %r vs %r (lon %s)', nl, -e, m, t, g, lon)
|
|
687
|
+
nl = NN
|
|
688
|
+
t = m.toLatLon(LatLon=LatLon)
|
|
689
|
+
d = max(fabs(t.lat - lat), fabs(t.lon - lon))
|
|
690
|
+
if d > 1e-9 and -90 < lat < 90 and -180 < lon < 180:
|
|
683
691
|
e += 1
|
|
684
|
-
printf('%s%6s: %s: %
|
|
692
|
+
printf('%s%6s: %s: %s vs %s %.6e', nl, -e, m, t.latlon,
|
|
693
|
+
(float(lat), float(lon)), d)
|
|
685
694
|
nl = NN
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
printf(nl)
|
|
697
|
-
|
|
698
|
-
p = e * 100.0 / n
|
|
699
|
-
printf('%6s: %s errors (%.2f%%)', n, (e if e else 'no'), p)
|
|
695
|
+
n += 1
|
|
696
|
+
if nl:
|
|
697
|
+
printf(' OK')
|
|
698
|
+
except KeyboardInterrupt:
|
|
699
|
+
printf(nl)
|
|
700
|
+
|
|
701
|
+
printf('%6s: %s errors (%s)', n, (e if e else 'no'), _fper(e, n, prec=2))
|
|
702
|
+
|
|
703
|
+
_main()
|
|
704
|
+
|
|
700
705
|
|
|
701
706
|
# % python3 -m pygeodesy.mgrs
|
|
702
707
|
# using: /opt/local/bin/GeoConvert -m ...
|
pygeodesy/named.py
CHANGED
|
@@ -34,7 +34,7 @@ from pygeodesy.streprs import attrs, Fmt, lrstrip, pairs, reprs, unstr
|
|
|
34
34
|
# from pygeodesy.units import _toUnit # _MODS
|
|
35
35
|
|
|
36
36
|
__all__ = _ALL_LAZY.named
|
|
37
|
-
__version__ = '24.
|
|
37
|
+
__version__ = '24.09.02'
|
|
38
38
|
|
|
39
39
|
_COMMANL_ = _COMMA_ + _NL_
|
|
40
40
|
_COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
|
|
@@ -214,8 +214,8 @@ class _Named(object):
|
|
|
214
214
|
def copy(self, deep=False, **name):
|
|
215
215
|
'''Make a shallow or deep copy of this instance.
|
|
216
216
|
|
|
217
|
-
@kwarg deep: If C{True} make a deep, otherwise
|
|
218
|
-
|
|
217
|
+
@kwarg deep: If C{True}, make a deep, otherwise a shallow
|
|
218
|
+
copy (C{bool}).
|
|
219
219
|
@kwarg name: Optional, non-empty C{B{name}=NN} (C{str}).
|
|
220
220
|
|
|
221
221
|
@return: The copy (C{This class}).
|
|
@@ -233,7 +233,8 @@ class _Named(object):
|
|
|
233
233
|
def dup(self, deep=False, **items):
|
|
234
234
|
'''Duplicate this instance, replacing some attributes.
|
|
235
235
|
|
|
236
|
-
@kwarg deep: If C{True} duplicate deep, otherwise shallow
|
|
236
|
+
@kwarg deep: If C{True}, duplicate deep, otherwise shallow
|
|
237
|
+
(C{bool}).
|
|
237
238
|
@kwarg items: Attributes to be changed (C{any}), including
|
|
238
239
|
optional C{B{name}} (C{str}).
|
|
239
240
|
|
|
@@ -890,6 +891,9 @@ class _NamedEnumItem(_NamedBase):
|
|
|
890
891
|
raise _AssertionError(t)
|
|
891
892
|
|
|
892
893
|
|
|
894
|
+
# from pygeodesy.props import _NamedProperty
|
|
895
|
+
|
|
896
|
+
|
|
893
897
|
class _NamedTuple(tuple, _Named):
|
|
894
898
|
'''(INTERNAL) Base for named C{tuple}s with both index I{and}
|
|
895
899
|
attribute name access to the items.
|