pygeodesy 24.8.24__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.24.dist-info → PyGeodesy-24.9.9.dist-info}/METADATA +3 -3
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.9.dist-info}/RECORD +40 -39
- pygeodesy/__init__.py +1 -1
- 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/auxLat.py +28 -36
- pygeodesy/auxilats/auxily.py +30 -50
- pygeodesy/basics.py +16 -5
- pygeodesy/booleans.py +10 -11
- pygeodesy/constants.py +26 -25
- pygeodesy/elliptic.py +154 -88
- pygeodesy/etm.py +71 -59
- pygeodesy/fmath.py +98 -90
- pygeodesy/fsums.py +198 -11
- 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/gxarea.py +3 -3
- pygeodesy/geodesicx/gxbases.py +32 -18
- pygeodesy/internals.py +50 -9
- pygeodesy/interns.py +3 -2
- pygeodesy/karney.py +83 -60
- pygeodesy/ktm.py +4 -4
- pygeodesy/lazily.py +8 -3
- pygeodesy/mgrs.py +47 -42
- pygeodesy/named.py +4 -1
- pygeodesy/props.py +7 -6
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +42 -60
- pygeodesy/triaxials.py +3 -3
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.9.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.8.24.dist-info → PyGeodesy-24.9.9.dist-info}/top_level.txt +0 -0
pygeodesy/internals.py
CHANGED
|
@@ -207,6 +207,13 @@ class _MODS_Base(object):
|
|
|
207
207
|
l3.insert(0, pypy)
|
|
208
208
|
return l3
|
|
209
209
|
|
|
210
|
+
@_Property_RO
|
|
211
|
+
def _Str_Bytes(self):
|
|
212
|
+
'''Get all C{str} and C{bytes} types.
|
|
213
|
+
'''
|
|
214
|
+
import pygeodesy.basics as m
|
|
215
|
+
return m._Strs + m._Bytes # + (range, map)
|
|
216
|
+
|
|
210
217
|
@_Property_RO
|
|
211
218
|
def streprs(self):
|
|
212
219
|
'''Get module C{pygeodesy.streprs}, I{once}.
|
|
@@ -254,6 +261,12 @@ def _enquote(strs, quote=_QUOTE2_, white=NN): # in .basics, .solveBase
|
|
|
254
261
|
return strs
|
|
255
262
|
|
|
256
263
|
|
|
264
|
+
def _fper(p, q, per=100.0, prec=1):
|
|
265
|
+
'''Format a percentage C{B{p} * B{per} / B{q}} (C{str}).
|
|
266
|
+
'''
|
|
267
|
+
return '%.*f%%' % (prec, (float(p) * per / float(q)))
|
|
268
|
+
|
|
269
|
+
|
|
257
270
|
def _headof(name):
|
|
258
271
|
'''(INTERNAL) Get the head name of qualified C{name} or the C{name}.
|
|
259
272
|
'''
|
|
@@ -292,6 +305,13 @@ def _isNix(): # in test/bases.py
|
|
|
292
305
|
return _MODS.nix2[0]
|
|
293
306
|
|
|
294
307
|
|
|
308
|
+
def _isPyChecker():
|
|
309
|
+
'''(INTERNAL) Is C{PyChecker} running? (C{bool}).
|
|
310
|
+
'''
|
|
311
|
+
# .../pychecker/checker.py --limit 0 --stdlib pygeodesy/<mod>/<name>.py
|
|
312
|
+
return _sys.argv[0].endswith('/pychecker/checker.py')
|
|
313
|
+
|
|
314
|
+
|
|
295
315
|
def _isPyPy(): # in test/bases.py
|
|
296
316
|
'''(INTERNAL) Is this C{PyPy}? (C{bool})
|
|
297
317
|
'''
|
|
@@ -343,12 +363,30 @@ def machine():
|
|
|
343
363
|
return _MODS.bits_machine2[1]
|
|
344
364
|
|
|
345
365
|
|
|
366
|
+
def _Math_K_2():
|
|
367
|
+
'''(INTERNAL) Return the I{Karney} Math setting.
|
|
368
|
+
'''
|
|
369
|
+
return _MODS.karney._wrapped.Math_K_2
|
|
370
|
+
|
|
371
|
+
|
|
346
372
|
def _name_version(pkg):
|
|
347
373
|
'''(INTERNAL) Return C{pskg.__name__ + ' ' + .__version__}.
|
|
348
374
|
'''
|
|
349
375
|
return _SPACE_(pkg.__name__, pkg.__version__)
|
|
350
376
|
|
|
351
377
|
|
|
378
|
+
def _name_binary(path):
|
|
379
|
+
'''(INTERNAL) Return C{(basename + ' ' + version)} of an executable.
|
|
380
|
+
'''
|
|
381
|
+
if path:
|
|
382
|
+
try:
|
|
383
|
+
_, r = _MODS.solveBase._popen2((path, '--version'))
|
|
384
|
+
return _SPACE_(_os_path.basename(path), r.split()[-1])
|
|
385
|
+
except (IndexError, IOError, OSError):
|
|
386
|
+
pass
|
|
387
|
+
return NN
|
|
388
|
+
|
|
389
|
+
|
|
352
390
|
def _osversion2(sep=NN): # in .lazily, test/bases.versions
|
|
353
391
|
'''(INTERNAL) Get the O/S name and release as C{2-list} or C{str}.
|
|
354
392
|
'''
|
|
@@ -463,15 +501,17 @@ def _secs2str(secs): # in .geoids, ../test/bases.py
|
|
|
463
501
|
return t
|
|
464
502
|
|
|
465
503
|
|
|
466
|
-
def _sizeof(obj):
|
|
504
|
+
def _sizeof(obj, deep=True):
|
|
467
505
|
'''(INTERNAL) Recursively size an C{obj}ect.
|
|
468
506
|
|
|
469
|
-
@
|
|
470
|
-
|
|
471
|
-
counting duplicates only once or
|
|
472
|
-
C{None}.
|
|
507
|
+
@kwarg deep: If C{True}, include the size of all
|
|
508
|
+
C{.__dict__.values()} (C{bool}).
|
|
473
509
|
|
|
474
|
-
@
|
|
510
|
+
@return: The C{obj} size in bytes (C{int}), ignoring
|
|
511
|
+
class attributes and counting instances only
|
|
512
|
+
once or C{None}.
|
|
513
|
+
|
|
514
|
+
@note: With C{PyPy}, the returned size is always C{None}.
|
|
475
515
|
'''
|
|
476
516
|
try:
|
|
477
517
|
_zB = _sys.getsizeof
|
|
@@ -491,9 +531,10 @@ def _sizeof(obj):
|
|
|
491
531
|
if isinstance(o, dict):
|
|
492
532
|
z += _zR(s, o.keys())
|
|
493
533
|
z += _zR(s, o.values())
|
|
494
|
-
elif _isiterablen(o)
|
|
534
|
+
elif _isiterablen(o) and not \
|
|
535
|
+
isinstance(o, _MODS._Str_Bytes):
|
|
495
536
|
z += _zR(s, o)
|
|
496
|
-
|
|
537
|
+
elif deep:
|
|
497
538
|
try: # size instance' attr values only
|
|
498
539
|
z += _zR(s, o.__dict__.values())
|
|
499
540
|
except AttributeError: # None, int, etc.
|
|
@@ -611,7 +652,7 @@ def _versions(sep=_SPACE_):
|
|
|
611
652
|
|
|
612
653
|
|
|
613
654
|
__all__ = tuple(map(_dunder_nameof, (machine, print_, printf)))
|
|
614
|
-
__version__ = '24.
|
|
655
|
+
__version__ = '24.09.04'
|
|
615
656
|
|
|
616
657
|
if _dunder_ismain(__name__): # PYCHOK no cover
|
|
617
658
|
|
pygeodesy/interns.py
CHANGED
|
@@ -200,6 +200,7 @@ _distant_ = _Prefix('distant') # PYCHOK OK
|
|
|
200
200
|
_doesn_t_exist_ = "doesn't exist" # PYCHOK OK
|
|
201
201
|
_DOT_ = Str_('.') # PYCHOK OK
|
|
202
202
|
_dunder_name_ = '__name__' # PYCHOK _DUNDER_(NN, _name_, NN)
|
|
203
|
+
_duplicate_ = 'duplicate' # PYCHOK OK
|
|
203
204
|
_e_ = 'e' # PYCHOK OK
|
|
204
205
|
_E_ = 'E' # PYCHOK OK
|
|
205
206
|
_earth_ = 'earth' # PYCHOK OK
|
|
@@ -347,7 +348,7 @@ _Python_ = _Python_('Python') # PYCHOK singleton
|
|
|
347
348
|
_python_ = 'python' # PYCHOK OK
|
|
348
349
|
_QUOTE1_ = "'" # PYCHOK OK
|
|
349
350
|
_QUOTE2_ = '"' # PYCHOK OK
|
|
350
|
-
|
|
351
|
+
_QUOTE3_ = "'''" # PYCHOK OK
|
|
351
352
|
# _QUOTE6_ = '"""' # PYCHOK OK
|
|
352
353
|
_R_ = 'R' # PYCHOK OK
|
|
353
354
|
_radians_ = 'radians' # PYCHOK OK
|
|
@@ -440,7 +441,7 @@ _LR_PAIRS = {_LANGLE_: _RANGLE_,
|
|
|
440
441
|
|
|
441
442
|
__all__ = (_NN_, # NOT MISSING!
|
|
442
443
|
Str_.__name__) # classes
|
|
443
|
-
__version__ = '24.08.
|
|
444
|
+
__version__ = '24.08.30'
|
|
444
445
|
|
|
445
446
|
if __name__ == '__main__':
|
|
446
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/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',
|
|
@@ -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/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_
|
|
@@ -891,6 +891,9 @@ class _NamedEnumItem(_NamedBase):
|
|
|
891
891
|
raise _AssertionError(t)
|
|
892
892
|
|
|
893
893
|
|
|
894
|
+
# from pygeodesy.props import _NamedProperty
|
|
895
|
+
|
|
896
|
+
|
|
894
897
|
class _NamedTuple(tuple, _Named):
|
|
895
898
|
'''(INTERNAL) Base for named C{tuple}s with both index I{and}
|
|
896
899
|
attribute name access to the items.
|
pygeodesy/props.py
CHANGED
|
@@ -25,12 +25,11 @@ from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, \
|
|
|
25
25
|
from functools import wraps as _wraps
|
|
26
26
|
|
|
27
27
|
__all__ = _ALL_LAZY.props
|
|
28
|
-
__version__ = '24.
|
|
28
|
+
__version__ = '24.09.02'
|
|
29
29
|
|
|
30
30
|
_class_ = 'class'
|
|
31
31
|
_dont_use_ = _DEPRECATED_ + ", don't use."
|
|
32
32
|
_function_ = 'function'
|
|
33
|
-
_get_and_set_ = 'get and set'
|
|
34
33
|
_has_been_ = 'has been' # PYCHOK used!
|
|
35
34
|
_method_ = 'method'
|
|
36
35
|
_not_an_inst_ = _not_(_an_, 'instance')
|
|
@@ -396,7 +395,9 @@ class property_ROver(_property_RO___):
|
|
|
396
395
|
# No __doc__ on purpose
|
|
397
396
|
|
|
398
397
|
def _fget(self, inst):
|
|
399
|
-
'''Get the C{property} value I{once} and overwrite C{self},
|
|
398
|
+
'''Get the C{property} value I{once} and overwrite C{self},
|
|
399
|
+
this C{property} instance in the (super-)class of C{self}
|
|
400
|
+
where this property is define as a L{property_ROver}.
|
|
400
401
|
'''
|
|
401
402
|
v = self.method(inst)
|
|
402
403
|
n = self.name
|
|
@@ -411,8 +412,8 @@ class property_ROver(_property_RO___):
|
|
|
411
412
|
return v
|
|
412
413
|
|
|
413
414
|
|
|
414
|
-
class _NamedProperty(property):
|
|
415
|
-
'''Class C{property} with
|
|
415
|
+
class _NamedProperty(property): # in .named
|
|
416
|
+
'''Class C{property} with a C{.name} attribute.
|
|
416
417
|
'''
|
|
417
418
|
@Property_RO
|
|
418
419
|
def name(self):
|
|
@@ -445,7 +446,7 @@ def property_doc_(doc):
|
|
|
445
446
|
def _documented_property(method):
|
|
446
447
|
'''(INTERNAL) Return the documented C{property}.
|
|
447
448
|
'''
|
|
448
|
-
t =
|
|
449
|
+
t = 'get and set' if doc.startswith(_SPACE_) else NN
|
|
449
450
|
return _NamedProperty(method, None, None, NN('Property to ', t, doc))
|
|
450
451
|
|
|
451
452
|
return _documented_property
|
pygeodesy/rhumb/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ u'''Package of lazily imported C{rhumb} modules L{rhumb.aux_}, L{rhumb.ekx} and
|
|
|
9
9
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER, _lazy_import_as, _unLazy0
|
|
10
10
|
|
|
11
11
|
__all__ = _ALL_LAZY.rhumb
|
|
12
|
-
__version__ = '24.
|
|
12
|
+
__version__ = '24.09.02'
|
|
13
13
|
|
|
14
14
|
if _unLazy0: # or _isfrozen
|
|
15
15
|
from pygeodesy.rhumb.aux_ import RhumbAux, RhumbLineAux
|