pygeodesy 24.9.29__py2.py3-none-any.whl → 24.10.24__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.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/METADATA +15 -15
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/RECORD +56 -56
- pygeodesy/__init__.py +20 -19
- pygeodesy/__main__.py +5 -5
- pygeodesy/albers.py +12 -17
- pygeodesy/basics.py +38 -41
- pygeodesy/booleans.py +54 -46
- pygeodesy/cartesianBase.py +2 -2
- pygeodesy/constants.py +20 -16
- pygeodesy/datums.py +3 -3
- pygeodesy/dms.py +250 -270
- pygeodesy/ellipsoidalBase.py +2 -2
- pygeodesy/ellipsoidalBaseDI.py +10 -10
- pygeodesy/ellipsoidalNvector.py +4 -4
- pygeodesy/ellipsoidalVincenty.py +2 -2
- pygeodesy/ellipsoids.py +7 -48
- pygeodesy/elliptic.py +14 -14
- pygeodesy/errors.py +15 -10
- pygeodesy/etm.py +18 -2
- pygeodesy/fmath.py +188 -176
- pygeodesy/formy.py +4 -4
- pygeodesy/fstats.py +54 -56
- pygeodesy/fsums.py +304 -266
- pygeodesy/geodesici.py +43 -40
- pygeodesy/geodesicw.py +3 -3
- pygeodesy/geodesicx/gxarea.py +3 -2
- pygeodesy/geodsolve.py +73 -24
- pygeodesy/geohash.py +2 -2
- pygeodesy/geoids.py +28 -27
- pygeodesy/internals.py +156 -85
- pygeodesy/interns.py +23 -20
- pygeodesy/karney.py +61 -12
- pygeodesy/latlonBase.py +13 -15
- pygeodesy/lazily.py +206 -214
- pygeodesy/mgrs.py +13 -13
- pygeodesy/named.py +11 -10
- pygeodesy/nvectorBase.py +1 -1
- pygeodesy/points.py +2 -2
- pygeodesy/props.py +34 -13
- pygeodesy/rhumb/bases.py +5 -5
- pygeodesy/rhumb/solve.py +7 -8
- pygeodesy/solveBase.py +7 -25
- pygeodesy/sphericalBase.py +20 -23
- pygeodesy/sphericalNvector.py +24 -23
- pygeodesy/sphericalTrigonometry.py +9 -8
- pygeodesy/streprs.py +11 -8
- pygeodesy/trf.py +6 -4
- pygeodesy/triaxials.py +46 -9
- pygeodesy/units.py +4 -3
- pygeodesy/ups.py +6 -6
- pygeodesy/utily.py +2 -2
- pygeodesy/utm.py +2 -2
- pygeodesy/vector3d.py +5 -5
- pygeodesy/vector3dBase.py +4 -5
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.9.29.dist-info → PyGeodesy-24.10.24.dist-info}/top_level.txt +0 -0
pygeodesy/internals.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
|
|
1
2
|
# -*- coding: utf-8 -*-
|
|
2
3
|
|
|
3
4
|
u'''Mostly INTERNAL functions, except L{machine}, L{print_} and L{printf}.
|
|
4
5
|
'''
|
|
5
|
-
# from pygeodesy.basics import isiterablen # _MODS
|
|
6
|
+
# from pygeodesy.basics import isiterablen, ubstr # _MODS
|
|
6
7
|
# from pygeodesy.errors import _AttributeError, _error_init, _UnexpectedError, _xError2 # _MODS
|
|
7
8
|
from pygeodesy.interns import NN, _BAR_, _COLON_, _DASH_, _DOT_, _ELLIPSIS_, _EQUALSPACED_, \
|
|
8
9
|
_immutable_, _NL_, _pygeodesy_, _PyPy__, _python_, _QUOTE1_, \
|
|
@@ -10,8 +11,8 @@ from pygeodesy.interns import NN, _BAR_, _COLON_, _DASH_, _DOT_, _ELLIPSIS_, _EQ
|
|
|
10
11
|
from pygeodesy.interns import _COMMA_, _Python_ # PYCHOK used!
|
|
11
12
|
# from pygeodesy.streprs import anstr, pairs, unstr # _MODS
|
|
12
13
|
|
|
13
|
-
import os
|
|
14
|
-
import os.path
|
|
14
|
+
# import os # _MODS
|
|
15
|
+
# import os.path # _MODS
|
|
15
16
|
# import sys as _sys # from .interns
|
|
16
17
|
|
|
17
18
|
_0_0 = 0.0 # PYCHOK in .basics, .constants
|
|
@@ -22,8 +23,8 @@ _SIsecs = 'fs', 'ps', 'ns', 'us', 'ms', 'sec' # reversed
|
|
|
22
23
|
_Windows_ = 'Windows'
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def
|
|
26
|
-
'''(INTERNAL) Get the
|
|
26
|
+
def _DUNDER_nameof(inst, *dflt):
|
|
27
|
+
'''(INTERNAL) Get the DUNDER C{.__name__} attr.
|
|
27
28
|
'''
|
|
28
29
|
try:
|
|
29
30
|
return inst.__name__
|
|
@@ -32,16 +33,16 @@ def _dunder_nameof(inst, *dflt):
|
|
|
32
33
|
return dflt[0] if dflt else inst.__class__.__name__
|
|
33
34
|
|
|
34
35
|
|
|
35
|
-
def
|
|
36
|
-
'''(INTERNAL) Yield the
|
|
36
|
+
def _DUNDER_nameof_(*names__): # in .errors._IsnotError
|
|
37
|
+
'''(INTERNAL) Yield the _DUNDER_nameof or name.
|
|
37
38
|
'''
|
|
38
|
-
return map(
|
|
39
|
+
return map(_DUNDER_nameof, names__, names__)
|
|
39
40
|
|
|
40
41
|
|
|
41
42
|
def _Property_RO(method):
|
|
42
43
|
'''(INTERNAL) Can't I{recursively} import L{props.property_RO}.
|
|
43
44
|
'''
|
|
44
|
-
name =
|
|
45
|
+
name = _DUNDER_nameof(method)
|
|
45
46
|
|
|
46
47
|
def _del(inst, attr): # PYCHOK no cover
|
|
47
48
|
delattr(inst, attr) # force error
|
|
@@ -67,9 +68,16 @@ class _MODS_Base(object):
|
|
|
67
68
|
self.__dict__.pop(attr, None)
|
|
68
69
|
|
|
69
70
|
def __setattr__(self, attr, value): # PYCHOK no cover
|
|
70
|
-
|
|
71
|
+
e = _MODS.errors
|
|
71
72
|
t = _EQUALSPACED_(self._DOT_(attr), repr(value))
|
|
72
|
-
raise
|
|
73
|
+
raise e._AttributeError(_immutable_, txt=t)
|
|
74
|
+
|
|
75
|
+
@_Property_RO
|
|
76
|
+
def basics(self):
|
|
77
|
+
'''Get module C{pygeodesy.basics}, I{once}.
|
|
78
|
+
'''
|
|
79
|
+
from pygeodesy import basics as b # DON'T _lazy_import2
|
|
80
|
+
return b
|
|
73
81
|
|
|
74
82
|
@_Property_RO
|
|
75
83
|
def bits_machine2(self):
|
|
@@ -98,6 +106,7 @@ class _MODS_Base(object):
|
|
|
98
106
|
|
|
99
107
|
def dlopen(name):
|
|
100
108
|
return _dlopen(name, DEFAULT_MODE)
|
|
109
|
+
|
|
101
110
|
else: # PYCHOK no cover
|
|
102
111
|
from ctypes import CDLL
|
|
103
112
|
dlopen = _passarg
|
|
@@ -119,8 +128,15 @@ class _MODS_Base(object):
|
|
|
119
128
|
def errors(self):
|
|
120
129
|
'''Get module C{pygeodesy.errors}, I{once}.
|
|
121
130
|
'''
|
|
122
|
-
from pygeodesy import errors # DON'T _lazy_import2
|
|
123
|
-
return
|
|
131
|
+
from pygeodesy import errors as e # DON'T _lazy_import2
|
|
132
|
+
return e
|
|
133
|
+
|
|
134
|
+
@_Property_RO
|
|
135
|
+
def inspect(self): # in .basics
|
|
136
|
+
'''Get module C{inspect}, I{once}.
|
|
137
|
+
'''
|
|
138
|
+
import inspect as i
|
|
139
|
+
return i
|
|
124
140
|
|
|
125
141
|
def ios_ver(self):
|
|
126
142
|
'''Mimick C{platform.xxx_ver} for C{iOS}.
|
|
@@ -141,7 +157,7 @@ class _MODS_Base(object):
|
|
|
141
157
|
def name(self):
|
|
142
158
|
'''Get this name (C{str}).
|
|
143
159
|
'''
|
|
144
|
-
return
|
|
160
|
+
return _DUNDER_nameof(self.__class__)
|
|
145
161
|
|
|
146
162
|
@_Property_RO
|
|
147
163
|
def nix2(self): # PYCHOK no cover
|
|
@@ -168,6 +184,14 @@ class _MODS_Base(object):
|
|
|
168
184
|
t = _version2(v, n=3) if v else (NN, NN, NN)
|
|
169
185
|
return v, t, machine()
|
|
170
186
|
|
|
187
|
+
@_Property_RO
|
|
188
|
+
def os(self):
|
|
189
|
+
'''Get module C{os}, I{once}.
|
|
190
|
+
'''
|
|
191
|
+
import os as o
|
|
192
|
+
import os.path
|
|
193
|
+
return o
|
|
194
|
+
|
|
171
195
|
@_Property_RO
|
|
172
196
|
def osversion2(self):
|
|
173
197
|
'''Get 2-list C{[OS, release]}, I{once}.
|
|
@@ -192,10 +216,21 @@ class _MODS_Base(object):
|
|
|
192
216
|
v = v()[0]
|
|
193
217
|
if v and n:
|
|
194
218
|
break
|
|
195
|
-
|
|
196
|
-
|
|
219
|
+
else:
|
|
220
|
+
n = v = NN # XXX AssertioError?
|
|
197
221
|
return [n, v]
|
|
198
222
|
|
|
223
|
+
@_Property_RO
|
|
224
|
+
def _Popen_kwds2(self):
|
|
225
|
+
'''(INTERNAL) Get C{subprocess.Popen} and C{-kwds}.
|
|
226
|
+
'''
|
|
227
|
+
import subprocess as _sub
|
|
228
|
+
kwds = dict(creationflags=0, # executable=sys.executable, shell=True,
|
|
229
|
+
stdin=_sub.PIPE, stdout=_sub.PIPE, stderr=_sub.STDOUT)
|
|
230
|
+
if _sys.version_info[:2] > (3, 6):
|
|
231
|
+
kwds.update(text=True)
|
|
232
|
+
return _sub.Popen, kwds
|
|
233
|
+
|
|
199
234
|
@_Property_RO
|
|
200
235
|
def Pythonarchine(self):
|
|
201
236
|
'''Get 3- or 4-list C{[PyPy, Python, bits, machine]}, I{once}.
|
|
@@ -208,46 +243,57 @@ class _MODS_Base(object):
|
|
|
208
243
|
return l3
|
|
209
244
|
|
|
210
245
|
@_Property_RO
|
|
211
|
-
def
|
|
212
|
-
'''Get
|
|
246
|
+
def streprs(self):
|
|
247
|
+
'''Get module C{pygeodesy.streprs}, I{once}.
|
|
213
248
|
'''
|
|
214
|
-
|
|
215
|
-
return
|
|
249
|
+
from pygeodesy import streprs as s # DON'T _lazy_import2
|
|
250
|
+
return s
|
|
216
251
|
|
|
217
252
|
@_Property_RO
|
|
218
|
-
def
|
|
219
|
-
'''Get
|
|
253
|
+
def sys_version_info2(self):
|
|
254
|
+
'''Get C{sys.version_inf0[:2], I{once}.
|
|
220
255
|
'''
|
|
221
|
-
|
|
222
|
-
return streprs
|
|
256
|
+
return _sys.version_info[:2]
|
|
223
257
|
|
|
224
258
|
@_Property_RO
|
|
225
259
|
def version(self):
|
|
226
260
|
'''Get pygeodesy version, I{once}.
|
|
227
261
|
'''
|
|
228
|
-
from pygeodesy import version
|
|
229
|
-
return
|
|
262
|
+
from pygeodesy import version as v
|
|
263
|
+
return v
|
|
230
264
|
|
|
231
265
|
_MODS = _MODS_Base() # PYCHOK overwritten by .lazily
|
|
232
266
|
|
|
233
267
|
|
|
234
|
-
def _caller3(up): # in .lazily, .named
|
|
268
|
+
def _caller3(up, base=True): # in .lazily, .named
|
|
235
269
|
'''(INTERNAL) Get 3-tuple C{(caller name, file name, line number)}
|
|
236
|
-
for the caller B{C{up}}
|
|
237
|
-
'''
|
|
238
|
-
# sys._getframe(1) ... 'importlib._bootstrap' line 1032,
|
|
239
|
-
# may throw a ValueError('call stack not deep enough')
|
|
240
|
-
f = _sys._getframe(up + 1)
|
|
241
|
-
c = f.f_code
|
|
242
|
-
return (c.co_name, # caller name
|
|
243
|
-
_os_path.basename(c.co_filename), # file name .py
|
|
244
|
-
f.f_lineno) # line number
|
|
245
|
-
|
|
270
|
+
for the caller B{C{up}} frames back in the Python call stack.
|
|
246
271
|
|
|
247
|
-
|
|
248
|
-
|
|
272
|
+
@kwarg base: Use C{B{base}=False} for the fully-qualified file
|
|
273
|
+
name, otherwise the base (module) name (C{bool}).
|
|
249
274
|
'''
|
|
250
|
-
|
|
275
|
+
f = None
|
|
276
|
+
_f = _MODS.os.path.basename if base else _passarg
|
|
277
|
+
try:
|
|
278
|
+
f = _sys._getframe(up + 1) # == inspect.stack()[up + 1][0]
|
|
279
|
+
t = _MODS.inspect.getframeinfo(f)
|
|
280
|
+
t = t.function, _f(t.filename), t.lineno
|
|
281
|
+
# or ...
|
|
282
|
+
# f = _sys._getframe(up + 1)
|
|
283
|
+
# c = f.f_code
|
|
284
|
+
# t = (c.co_name, # caller name
|
|
285
|
+
# _f(c.co_filename), # file name .py
|
|
286
|
+
# f.f_lineno) # line number
|
|
287
|
+
# or ...
|
|
288
|
+
# t = _MODS.inspect.stack()[up + 1] # (frame, filename, lineno, function, ...)
|
|
289
|
+
# t = t[3], _f(t[1]), t[2]
|
|
290
|
+
except (AttributeError, IndexError, ValueError):
|
|
291
|
+
# sys._getframe(1) ... 'importlib._bootstrap' line 1032,
|
|
292
|
+
# may throw a ValueError('call stack not deep enough')
|
|
293
|
+
t = NN, NN, 0
|
|
294
|
+
finally:
|
|
295
|
+
del f # break ref cycle
|
|
296
|
+
return t
|
|
251
297
|
|
|
252
298
|
|
|
253
299
|
def _enquote(strs, quote=_QUOTE2_, white=NN): # in .basics, .solveBase
|
|
@@ -267,6 +313,15 @@ def _fper(p, q, per=100.0, prec=1):
|
|
|
267
313
|
return '%.*f%%' % (prec, (float(p) * per / float(q)))
|
|
268
314
|
|
|
269
315
|
|
|
316
|
+
_getenv = _MODS.os.getenv # PYCHOK in .lazily, ...
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def _getPYGEODESY(which, dflt=NN):
|
|
320
|
+
'''(INTERNAL) Return an C{PYGEODESY_...} ENV value or C{dflt}.
|
|
321
|
+
'''
|
|
322
|
+
return _getenv(_PYGEODESY(which), dflt)
|
|
323
|
+
|
|
324
|
+
|
|
270
325
|
def _headof(name):
|
|
271
326
|
'''(INTERNAL) Get the head name of qualified C{name} or the C{name}.
|
|
272
327
|
'''
|
|
@@ -280,26 +335,32 @@ def _headof(name):
|
|
|
280
335
|
# return (a == b) if _isPyPy() else (a is b)
|
|
281
336
|
|
|
282
337
|
|
|
283
|
-
def
|
|
284
|
-
'''(INTERNAL) Is this C{Apple Silicon}? (C{bool})
|
|
338
|
+
def _isAppleSi():
|
|
339
|
+
'''(INTERNAL) Is this C{macOS on Apple Silicon}? (C{bool})
|
|
285
340
|
'''
|
|
286
341
|
return _ismacOS() and machine().startswith(_arm64_)
|
|
287
342
|
|
|
288
343
|
|
|
289
|
-
def
|
|
344
|
+
def _is_DUNDER_main(name):
|
|
345
|
+
'''(INTERNAL) Return C{bool(name == '__main__')}.
|
|
346
|
+
'''
|
|
347
|
+
return name == '__main__'
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def _isiOS(): # in test/bases
|
|
290
351
|
'''(INTERNAL) Is this C{iOS}? (C{bool})
|
|
291
352
|
'''
|
|
292
353
|
return _MODS.osversion2[0] is _iOS_
|
|
293
354
|
|
|
294
355
|
|
|
295
|
-
def _ismacOS(): # in test/bases
|
|
356
|
+
def _ismacOS(): # in test/bases
|
|
296
357
|
'''(INTERNAL) Is this C{macOS}? (C{bool})
|
|
297
358
|
'''
|
|
298
359
|
return _sys.platform[:6] == 'darwin' and \
|
|
299
|
-
_MODS.osversion2[0] is _macOS_ # and os.name == 'posix'
|
|
360
|
+
_MODS.osversion2[0] is _macOS_ # and _MODS.os.name == 'posix'
|
|
300
361
|
|
|
301
362
|
|
|
302
|
-
def _isNix(): # in test/bases
|
|
363
|
+
def _isNix(): # in test/bases
|
|
303
364
|
'''(INTERNAL) Is this a C{Linux} distro? (C{str} or L{NN})
|
|
304
365
|
'''
|
|
305
366
|
return _MODS.nix2[0]
|
|
@@ -312,14 +373,14 @@ def _isPyChecker():
|
|
|
312
373
|
return _sys.argv[0].endswith('/pychecker/checker.py')
|
|
313
374
|
|
|
314
375
|
|
|
315
|
-
def _isPyPy(): # in test/bases
|
|
376
|
+
def _isPyPy(): # in test/bases
|
|
316
377
|
'''(INTERNAL) Is this C{PyPy}? (C{bool})
|
|
317
378
|
'''
|
|
318
379
|
# platform.python_implementation() == 'PyPy'
|
|
319
380
|
return _MODS.Pythonarchine[0].startswith(_PyPy__)
|
|
320
381
|
|
|
321
382
|
|
|
322
|
-
def _isWindows(): # in test/bases
|
|
383
|
+
def _isWindows(): # in test/bases
|
|
323
384
|
'''(INTERNAL) Is this C{Windows}? (C{bool})
|
|
324
385
|
'''
|
|
325
386
|
return _sys.platform[:3] == 'win' and \
|
|
@@ -338,8 +399,8 @@ def _load_lib(name):
|
|
|
338
399
|
ns = find_lib(name), name
|
|
339
400
|
if dlopen is not _passarg: # _ismacOS()
|
|
340
401
|
ns += (_DOT_(name, 'dylib'),
|
|
341
|
-
_DOT_(name, 'framework'),
|
|
342
|
-
_DOT_(name, 'framework'),
|
|
402
|
+
_DOT_(name, 'framework'), _MODS.os.path.join(
|
|
403
|
+
_DOT_(name, 'framework'), name))
|
|
343
404
|
for n in ns:
|
|
344
405
|
try:
|
|
345
406
|
if n and dlopen(n): # pre-load handle
|
|
@@ -363,30 +424,12 @@ def machine():
|
|
|
363
424
|
return _MODS.bits_machine2[1]
|
|
364
425
|
|
|
365
426
|
|
|
366
|
-
def _Math_K_2():
|
|
367
|
-
'''(INTERNAL) Return the I{Karney} Math setting.
|
|
368
|
-
'''
|
|
369
|
-
return _MODS.karney._wrapped.Math_K_2
|
|
370
|
-
|
|
371
|
-
|
|
372
427
|
def _name_version(pkg):
|
|
373
428
|
'''(INTERNAL) Return C{pskg.__name__ + ' ' + .__version__}.
|
|
374
429
|
'''
|
|
375
430
|
return _SPACE_(pkg.__name__, pkg.__version__)
|
|
376
431
|
|
|
377
432
|
|
|
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
|
-
|
|
390
433
|
def _osversion2(sep=NN): # in .lazily, test/bases.versions
|
|
391
434
|
'''(INTERNAL) Get the O/S name and release as C{2-list} or C{str}.
|
|
392
435
|
'''
|
|
@@ -412,6 +455,16 @@ def _plural(noun, n, nn=NN):
|
|
|
412
455
|
return NN(noun, _s_) if n > 1 else (noun if n else nn)
|
|
413
456
|
|
|
414
457
|
|
|
458
|
+
def _popen2(cmd, stdin=None): # in .mgrs, .solveBase, .testMgrs
|
|
459
|
+
'''(INTERNAL) Invoke C{B{cmd} tuple} and return 2-tuple C{(std, status)}
|
|
460
|
+
with all C{stdout/-err} output, I{stripped} and C{int} exit status.
|
|
461
|
+
'''
|
|
462
|
+
_Popen, kwds = _MODS._Popen_kwds2
|
|
463
|
+
p = _Popen(cmd, **kwds) # PYCHOK kwArgs
|
|
464
|
+
r = p.communicate(stdin)[0] # stdout + NL + stderr
|
|
465
|
+
return _MODS.basics.ub2str(r).strip(), p.returncode
|
|
466
|
+
|
|
467
|
+
|
|
415
468
|
def print_(*args, **nl_nt_prec_prefix__end_file_flush_sep__kwds): # PYCHOK no cover
|
|
416
469
|
'''Python 3+ C{print}-like formatting and printing.
|
|
417
470
|
|
|
@@ -475,17 +528,27 @@ def _print7(nl=0, nt=0, prec=6, prefix=NN, sep=_SPACE_, file=_sys.stdout,
|
|
|
475
528
|
return prefix, end, file, flush, prec, sep, kwds
|
|
476
529
|
|
|
477
530
|
|
|
478
|
-
def
|
|
531
|
+
def _PYGEODESY(which, i=0):
|
|
532
|
+
'''(INTERNAL) Return an ENV C{str} C{PYGEODESY_...}.
|
|
533
|
+
'''
|
|
534
|
+
try:
|
|
535
|
+
w = which.__name__.lstrip(_UNDER_)[i:]
|
|
536
|
+
except AttributeError:
|
|
537
|
+
w = which
|
|
538
|
+
return _UNDER_(_pygeodesy_, w).upper()
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def _Pythonarchine(sep=NN): # in .lazily, test/bases versions
|
|
479
542
|
'''(INTERNAL) Get PyPy and Python versions, bits and machine as C{3- or 4-list} or C{str}.
|
|
480
543
|
'''
|
|
481
544
|
l3 = _MODS.Pythonarchine
|
|
482
545
|
return sep.join(l3) if sep else l3 # 3- or 4-list
|
|
483
546
|
|
|
484
547
|
|
|
485
|
-
def _secs2str(secs): # in .geoids, ../test/bases
|
|
548
|
+
def _secs2str(secs): # in .geoids, ../test/bases
|
|
486
549
|
'''Convert a time in C{secs} to C{str}.
|
|
487
550
|
'''
|
|
488
|
-
if secs <
|
|
551
|
+
if secs < 100.0: # _100_0
|
|
489
552
|
unit = len(_SIsecs) - 1
|
|
490
553
|
while 0 < secs < 1 and unit > 0:
|
|
491
554
|
secs *= 1e3 # _1000_0
|
|
@@ -519,7 +582,9 @@ def _sizeof(obj, deep=True):
|
|
|
519
582
|
except TypeError: # PyPy3.10
|
|
520
583
|
return None
|
|
521
584
|
|
|
522
|
-
|
|
585
|
+
b = _MODS.basics
|
|
586
|
+
_isiterablen = b.isiterablen
|
|
587
|
+
_Str_Bytes = b._Strs + b._Bytes # + (range, map)
|
|
523
588
|
|
|
524
589
|
def _zR(s, iterable):
|
|
525
590
|
z, _s = 0, s.add
|
|
@@ -532,7 +597,7 @@ def _sizeof(obj, deep=True):
|
|
|
532
597
|
z += _zR(s, o.keys())
|
|
533
598
|
z += _zR(s, o.values())
|
|
534
599
|
elif _isiterablen(o) and not \
|
|
535
|
-
isinstance(o,
|
|
600
|
+
isinstance(o, _Str_Bytes):
|
|
536
601
|
z += _zR(s, o)
|
|
537
602
|
elif deep:
|
|
538
603
|
try: # size instance' attr values only
|
|
@@ -554,7 +619,7 @@ def _sysctl_uint(name):
|
|
|
554
619
|
u = uint(0)
|
|
555
620
|
z = size_t(sizeof(u))
|
|
556
621
|
r = libc.sysctlbyname(char_p(n), byref(u), byref(z), None, size_t(0))
|
|
557
|
-
else: #
|
|
622
|
+
else: # couldn't find or load 'libc'
|
|
558
623
|
r = -2
|
|
559
624
|
return int(r if r else u.value) # -1 ENOENT error, -2 no libc
|
|
560
625
|
|
|
@@ -596,17 +661,20 @@ def _usage(file_py, *args, **opts_help): # in .etm, .geodesici
|
|
|
596
661
|
|
|
597
662
|
args = _help(**opts_help) or (tuple(_opts(**opts_help)) + args)
|
|
598
663
|
|
|
599
|
-
u = _COLON_(
|
|
664
|
+
u = _COLON_(_DUNDER_nameof(_usage)[1:], NN)
|
|
600
665
|
return _SPACE_(u, *_usage_argv(file_py, *args))
|
|
601
666
|
|
|
602
667
|
|
|
603
668
|
def _usage_argv(argv0, *args):
|
|
604
669
|
'''(INTERNAL) Return 3-tuple C{(python, '-m', module, *args)}.
|
|
605
670
|
'''
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
671
|
+
o = _MODS.os
|
|
672
|
+
m = o.path.dirname(argv0)
|
|
673
|
+
m = m.replace(o.getcwd(), _ELLIPSIS_) \
|
|
674
|
+
.replace(o.sep, _DOT_).strip()
|
|
675
|
+
b = o.path.basename(argv0)
|
|
676
|
+
b, x = o.path.splitext(b)
|
|
677
|
+
if x == '.py' and not _is_DUNDER_main(b):
|
|
610
678
|
m = _DOT_(m or _pygeodesy_, b)
|
|
611
679
|
p = NN(_python_, _sys.version_info[0])
|
|
612
680
|
return (p, '-m', _enquote(m)) + args
|
|
@@ -651,15 +719,18 @@ def _versions(sep=_SPACE_):
|
|
|
651
719
|
return sep.join(l7) if sep else l7 # 5- or 6-list
|
|
652
720
|
|
|
653
721
|
|
|
654
|
-
__all__ = tuple(map(
|
|
655
|
-
__version__ = '24.
|
|
722
|
+
__all__ = tuple(map(_DUNDER_nameof, (machine, print_, printf)))
|
|
723
|
+
__version__ = '24.10.20'
|
|
724
|
+
|
|
725
|
+
if _is_DUNDER_main(__name__): # PYCHOK no cover
|
|
656
726
|
|
|
657
|
-
|
|
727
|
+
def _main():
|
|
728
|
+
from pygeodesy import _isfrozen, isLazy
|
|
658
729
|
|
|
659
|
-
|
|
730
|
+
print_(*(_versions(sep=NN) + ['_isfrozen', _isfrozen,
|
|
731
|
+
'isLazy', isLazy]))
|
|
660
732
|
|
|
661
|
-
|
|
662
|
-
'isLazy', isLazy]))
|
|
733
|
+
_main()
|
|
663
734
|
|
|
664
735
|
# **) MIT License
|
|
665
736
|
#
|
pygeodesy/interns.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
u'''Single C{str}ing constants, C{intern}'ed across C{pygeodesy}
|
|
4
4
|
modules and function L{pygeodesy.machine}.
|
|
5
5
|
'''
|
|
6
|
-
import sys as _sys
|
|
6
|
+
import sys as _sys # in .internals, .lazily
|
|
7
7
|
try:
|
|
8
8
|
_intern = intern # PYCHOK in .lazily, .trf
|
|
9
9
|
except NameError: # Python 3+
|
|
@@ -11,7 +11,7 @@ except NameError: # Python 3+
|
|
|
11
11
|
|
|
12
12
|
_COMMASPACE_ = ', ' # overriden below
|
|
13
13
|
_SUB_PACKAGES = 'auxilats', 'deprecated', 'geodesicx', 'rhumb' # PYCHOK in ...
|
|
14
|
-
# ... .lazily, make._dist, MANIFEST, setup.setup, test
|
|
14
|
+
# ... .lazily, make._dist, MANIFEST, setup.setup, test/bases, test/testModules
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class _Dash(str):
|
|
@@ -199,7 +199,8 @@ _distance_ = 'distance' # PYCHOK OK
|
|
|
199
199
|
_distant_ = _Prefix('distant') # PYCHOK OK
|
|
200
200
|
_doesn_t_exist_ = "doesn't exist" # PYCHOK OK
|
|
201
201
|
_DOT_ = Str_('.') # PYCHOK OK
|
|
202
|
-
|
|
202
|
+
_DUNDER_all_ = '__all__' # PYCHOK OK
|
|
203
|
+
_DUNDER_name_ = '__name__' # PYCHOK _DUNDER_(NN, _name_, NN)
|
|
203
204
|
_duplicate_ = 'duplicate' # PYCHOK OK
|
|
204
205
|
_e_ = 'e' # PYCHOK OK
|
|
205
206
|
_E_ = 'E' # PYCHOK OK
|
|
@@ -309,7 +310,6 @@ _negative_ = 'negative' # PYCHOK OK
|
|
|
309
310
|
_NL_ = Str_('\n') # PYCHOK OK
|
|
310
311
|
_NLATvar_ = Str_(_NL_ + '@var ') # PYCHOK OK
|
|
311
312
|
_NLHASH_ = Str_(_NL_ + '# ') # PYCHOK OK
|
|
312
|
-
# _NLNL_ = _DNL_ # PYCHOK OK
|
|
313
313
|
_NN_ = 'NN' # PYCHOK OK
|
|
314
314
|
_no_ = _Prefix('no') # PYCHOK OK
|
|
315
315
|
_northing_ = 'northing' # PYCHOK OK
|
|
@@ -341,7 +341,7 @@ _points_ = 'points' # PYCHOK OK
|
|
|
341
341
|
_pole_ = 'pole' # PYCHOK OK
|
|
342
342
|
_precision_ = 'precision' # PYCHOK OK
|
|
343
343
|
_prime_vertical_ = 'prime_vertical' # PYCHOK OK
|
|
344
|
-
_pygeodesy_ = 'pygeodesy' # PYCHOK OK
|
|
344
|
+
_pygeodesy_ = 'pygeodesy' # PYCHOK OK # in test/bases
|
|
345
345
|
_pygeodesy_abspath_ = 'pygeodesy_abspath' # PYCHOK OK
|
|
346
346
|
_PyPy__ = _PyPy__('PyPy ') # PYCHOK + _SPACE_
|
|
347
347
|
_Python_ = _Python_('Python') # PYCHOK singleton
|
|
@@ -429,7 +429,7 @@ _SW_ = _S_ + _W_ # PYCHOK negative ones
|
|
|
429
429
|
|
|
430
430
|
_DDOT_ = Str_(_DOT_ * 2) # PYCHOK OK
|
|
431
431
|
# _DEQUAL_ = Str_(_EQUAL_ * 2) # PYCHOK OK
|
|
432
|
-
_DNL_
|
|
432
|
+
# _DNL_ = Str_(_NL_ * 2) # PYCHOK OK
|
|
433
433
|
# _DSLASH_ = Str_(_SLASH_ * 2) # PYCHOK OK
|
|
434
434
|
# _DSTAR_ = Str_(_STAR_ * 2) # PYCHOK OK
|
|
435
435
|
_DUNDER_ = Str_(_UNDER_ * 2) # PYCHOK OK
|
|
@@ -441,23 +441,26 @@ _LR_PAIRS = {_LANGLE_: _RANGLE_,
|
|
|
441
441
|
|
|
442
442
|
__all__ = (_NN_, # NOT MISSING!
|
|
443
443
|
Str_.__name__) # classes
|
|
444
|
-
__version__ = '24.
|
|
444
|
+
__version__ = '24.10.19'
|
|
445
445
|
|
|
446
446
|
if __name__ == '__main__':
|
|
447
447
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
448
|
+
def _main():
|
|
449
|
+
from pygeodesy import itemsorted, printf
|
|
450
|
+
|
|
451
|
+
t = b = 0
|
|
452
|
+
for n, v in itemsorted(locals(), asorted=False, reverse=True):
|
|
453
|
+
if n.endswith(_UNDER_) and n.startswith(_UNDER_) and \
|
|
454
|
+
not n.startswith(_DUNDER_):
|
|
455
|
+
t += 1
|
|
456
|
+
b += len(v)
|
|
457
|
+
m = n[1:-1]
|
|
458
|
+
if m != v and m.replace(_UNDER_, _SPACE_) != v:
|
|
459
|
+
printf('%4d: %s = %r', t, n, v)
|
|
460
|
+
n = len(locals())
|
|
461
|
+
printf('%4d (%d) names, %s chars total, %.2f chars avg', t, n, b, float(b) / t, nl=1)
|
|
462
|
+
|
|
463
|
+
_main()
|
|
461
464
|
|
|
462
465
|
# **) MIT License
|
|
463
466
|
#
|
pygeodesy/karney.py
CHANGED
|
@@ -143,18 +143,18 @@ in C{pygeodesy} are based on I{Karney}'s post U{Area of a spherical polygon
|
|
|
143
143
|
# make sure int/int division yields float quotient, see .basics
|
|
144
144
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
145
145
|
|
|
146
|
-
from pygeodesy.basics import _copysign, isint, neg, unsigned0,
|
|
147
|
-
_zip
|
|
146
|
+
from pygeodesy.basics import _copysign, isint, neg, unsigned0, \
|
|
147
|
+
_xgeographiclib, _zip
|
|
148
148
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
|
|
149
149
|
_1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
150
150
|
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds
|
|
151
151
|
from pygeodesy.fmath import cbrt, fremainder, norm2 # Fhorner, Fsum
|
|
152
|
-
|
|
153
|
-
from pygeodesy.interns import NN,
|
|
152
|
+
from pygeodesy.internals import _getenv, _popen2, _PYGEODESY, _version_info
|
|
153
|
+
from pygeodesy.interns import NN, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
154
154
|
_composite_, _lat1_, _lat2_, _lon1_, _lon2_, \
|
|
155
155
|
_m12_, _M12_, _M21_, _number_, _s12_, _S12_, \
|
|
156
|
-
_UNDER_, _X_, _BAR_ # PYCHOK used!
|
|
157
|
-
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
156
|
+
_SPACE_, _UNDER_, _X_, _1_, _2_, _BAR_ # PYCHOK used!
|
|
157
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
158
158
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
159
159
|
from pygeodesy.props import deprecated_method, Property_RO, property_RO, \
|
|
160
160
|
property_ROnce
|
|
@@ -165,11 +165,12 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
165
165
|
# from math import fabs # from .utily
|
|
166
166
|
|
|
167
167
|
__all__ = _ALL_LAZY.karney
|
|
168
|
-
__version__ = '24.
|
|
168
|
+
__version__ = '24.10.14'
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
_2_4_ = '2.4'
|
|
171
|
+
_K_2_0 = _getenv(_PYGEODESY(_xgeographiclib, 1), _2_)
|
|
172
|
+
_K_2_4 = _K_2_0 == _2_4_
|
|
173
|
+
_K_2_0 = _K_2_4 or (_K_2_0 == _2_)
|
|
173
174
|
_perimeter_ = 'perimeter'
|
|
174
175
|
|
|
175
176
|
|
|
@@ -576,8 +577,8 @@ class _kWrapped(object): # in .geodesicw
|
|
|
576
577
|
|
|
577
578
|
@property_RO
|
|
578
579
|
def Math_K_2(self):
|
|
579
|
-
return (
|
|
580
|
-
(
|
|
580
|
+
return (_2_4_ if _K_2_4 else
|
|
581
|
+
(_2_ if _K_2_0 else _1_)) if self.Math else NN
|
|
581
582
|
|
|
582
583
|
_wrapped = _kWrapped() # PYCHOK singleton, .datum, .test/base.py
|
|
583
584
|
|
|
@@ -639,6 +640,54 @@ class Rhumb8Tuple(_GTuple):
|
|
|
639
640
|
return _MODS.deprecated.classes.Rhumb7Tuple(self[:-1])
|
|
640
641
|
|
|
641
642
|
|
|
643
|
+
class _Xables(object):
|
|
644
|
+
'''(INTERNAL) Get I{Karney}'s executable paths from/and env vars.
|
|
645
|
+
'''
|
|
646
|
+
bin_ = '/opt/local/bin/' # '/opt/local/Cellar/geographiclib/2.3/bin/' # HomeBrew on macOS
|
|
647
|
+
ENV = NN
|
|
648
|
+
|
|
649
|
+
def GeoConvert(self, *dir_):
|
|
650
|
+
return self._path(self.GeoConvert, *dir_)
|
|
651
|
+
|
|
652
|
+
def GeodSolve(self, *dir_):
|
|
653
|
+
return self._path(self.GeodSolve, *dir_)
|
|
654
|
+
|
|
655
|
+
def IntersectTool(self, *dir_):
|
|
656
|
+
return self._path(self.IntersectTool, *dir_)
|
|
657
|
+
|
|
658
|
+
def RhumbSolve(self, *dir_):
|
|
659
|
+
return self._path(self.RhumbSolve, *dir_)
|
|
660
|
+
|
|
661
|
+
def name_version(self, path, base=True):
|
|
662
|
+
# return C{(path + ' ' + version)} of an executable
|
|
663
|
+
if path:
|
|
664
|
+
try:
|
|
665
|
+
r, s = _popen2((path, '--version'))
|
|
666
|
+
if base:
|
|
667
|
+
path = _MODS.os.path.basename(path)
|
|
668
|
+
r = _SPACE_(path, r.split()[-1])
|
|
669
|
+
else:
|
|
670
|
+
r = _MODS.streprs.Fmt.PARENSPACED(r, s)
|
|
671
|
+
return r
|
|
672
|
+
except (IndexError, IOError, OSError):
|
|
673
|
+
pass
|
|
674
|
+
return NN
|
|
675
|
+
|
|
676
|
+
def _path(self, which, *dir_):
|
|
677
|
+
self.ENV = E = _PYGEODESY(which)
|
|
678
|
+
return _getenv(E, NN) or \
|
|
679
|
+
(NN(dir_[0], which.__name__) if dir_ else E)
|
|
680
|
+
|
|
681
|
+
def X_not(self, path):
|
|
682
|
+
return 'env %s=%r not executable' % (self.ENV, path)
|
|
683
|
+
|
|
684
|
+
def X_OK(self, path): # is C{path} an executable?
|
|
685
|
+
os = _MODS.os # import os
|
|
686
|
+
return os.access(path, os.X_OK) if path else False
|
|
687
|
+
|
|
688
|
+
_Xables = _Xables() # PYCHOK singleton
|
|
689
|
+
|
|
690
|
+
|
|
642
691
|
def _around(x): # in .utily.sincos2d
|
|
643
692
|
'''I{Coarsen} a scalar by rounding small values to underflow to C{0.0}.
|
|
644
693
|
|