pygeodesy 24.6.24__py2.py3-none-any.whl → 24.7.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.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/METADATA +25 -23
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/RECORD +38 -38
- pygeodesy/__init__.py +52 -46
- pygeodesy/__main__.py +6 -1
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/basics.py +8 -4
- pygeodesy/cartesianBase.py +5 -6
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +10 -3
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/errors.py +10 -1
- pygeodesy/fsums.py +12 -6
- pygeodesy/geodesici.py +1218 -330
- pygeodesy/geodesicw.py +69 -42
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/gx.py +20 -31
- pygeodesy/geodesicx/gxline.py +84 -73
- pygeodesy/geodsolve.py +44 -56
- pygeodesy/geoids.py +8 -10
- pygeodesy/internals.py +40 -13
- pygeodesy/karney.py +127 -74
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +4 -5
- pygeodesy/lazily.py +25 -22
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +4 -4
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +21 -22
- pygeodesy/solveBase.py +196 -128
- pygeodesy/triaxials.py +4 -5
- pygeodesy/units.py +5 -5
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.24.dist-info → PyGeodesy-24.7.24.dist-info}/top_level.txt +0 -0
pygeodesy/karney.py
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
u'''Wrapper around several C{geomath.Math} functions from I{Karney}'s Python package U{geographiclib
|
|
5
5
|
<https://PyPI.org/project/geographiclib>}, provided that package is installed.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
either by C{key} or by C{attribute} name.
|
|
9
|
-
All methods of the I{wrapped} L{Geodesic<geodesicw.Geodesic>} and L{GeodesicLine<geodesicw.GeodesicLine>}
|
|
7
|
+
Methods of the I{wrapped} L{Geodesic<geodesicw.Geodesic>} and L{GeodesicLine<geodesicw.GeodesicLine>}
|
|
10
8
|
classes return a L{GDict} instance offering access to the C{dict} items either by C{key} or by
|
|
11
9
|
C{attribute} name.
|
|
12
10
|
|
|
13
|
-
With env variable C{PYGEODESY_GEOGRAPHICLIB} left undefined or set to C{"2"}, modules L{
|
|
14
|
-
L{
|
|
11
|
+
With env variable C{PYGEODESY_GEOGRAPHICLIB} left undefined or set to C{"2"}, modules L{geodesicw},
|
|
12
|
+
L{geodesicx} and this module will use U{GeographicLib 2.0+<https://GeographicLib.SourceForge.io/C++/doc/>}
|
|
15
13
|
and newer transcoding, otherwise C{1.52} or older.
|
|
16
14
|
|
|
17
15
|
Karney-based functionality
|
|
@@ -60,8 +58,11 @@ Karney-based functionality
|
|
|
60
58
|
- L{GnomonicExact}, L{GnomonicGeodSolve}, L{GnomonicKarney} -- U{Gnomonic
|
|
61
59
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Gnomonic.html>}
|
|
62
60
|
|
|
61
|
+
- L{Intersector} -- U{Intersect
|
|
62
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Intersect.html>} from I{GeographicLib 2.3+}
|
|
63
|
+
|
|
63
64
|
- L{JacobiConformal} -- U{JacobiConformal
|
|
64
|
-
<https://
|
|
65
|
+
<https://geographiclib.sourceforge.io/C++/doc/classGeographicLib_1_1experimental_1_1JacobiConformal.html>}
|
|
65
66
|
|
|
66
67
|
- L{KTransverseMercator} - U{TransverseMercator
|
|
67
68
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1TransverseMercator.html>}
|
|
@@ -94,13 +95,14 @@ are I{transcoded} from C++ classes in I{Karney}'s U{GeographicLib<https://Geogra
|
|
|
94
95
|
|
|
95
96
|
2. These C{pygeodesy} modules and classes
|
|
96
97
|
|
|
97
|
-
- L{ellipsoidalGeodSolve}, L{ellipsoidalKarney}, L{geodsolve}, L{karney}, L{rhumb.solve}
|
|
98
|
+
- L{ellipsoidalGeodSolve}, L{ellipsoidalKarney}, L{geodesici}, L{geodsolve}, L{karney}, L{rhumb.solve}
|
|
98
99
|
- L{EquidistantKarney}, L{FrechetKarney}, L{GeodesicSolve}, L{GeodesicLineSolve}, L{GnomonicGeodSolve},
|
|
99
|
-
L{GnomonicKarney}, L{HeightIDWkarney}
|
|
100
|
+
L{GnomonicKarney}, L{HeightIDWkarney}, L{Intersectool}
|
|
100
101
|
|
|
101
|
-
are or use I{wrappers} around I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>}
|
|
102
|
-
C
|
|
103
|
-
|
|
102
|
+
are or use I{wrappers} around I{Karney}'s Python U{geographiclib<https://PyPI.org/project/geographiclib>} or
|
|
103
|
+
C++ utility U{GeodSolve<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>},
|
|
104
|
+
U{IntersectTool<https://GeographicLib.SourceForge.io/C++/doc/IntersectTool.1.html>} or
|
|
105
|
+
U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}.
|
|
104
106
|
|
|
105
107
|
3. All C{pygeodesy} functions and methods to compute I{ellipsoidal} intersections, nearest points and trilaterations
|
|
106
108
|
|
|
@@ -139,20 +141,20 @@ in C{pygeodesy} are based on I{Karney}'s post U{Area of a spherical polygon
|
|
|
139
141
|
# make sure int/int division yields float quotient, see .basics
|
|
140
142
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
141
143
|
|
|
142
|
-
from pygeodesy.basics import _copysign,
|
|
143
|
-
|
|
144
|
+
from pygeodesy.basics import _copysign, isint, neg, unsigned0, _xgeographiclib, \
|
|
145
|
+
_zip, _version_info
|
|
144
146
|
from pygeodesy.constants import NAN, _isfinite as _math_isfinite, _0_0, \
|
|
145
147
|
_1_16th, _1_0, _2_0, _180_0, _N_180_0, _360_0
|
|
146
148
|
from pygeodesy.errors import GeodesicError, _ValueError, _xkwds, _xkwds_get1
|
|
147
149
|
from pygeodesy.fmath import cbrt, fremainder, norm2
|
|
148
150
|
# from pygeodesy.internals import _version_info # from .basics
|
|
149
|
-
from pygeodesy.interns import _2_, _a12_, _area_, _azi2_, _azi12_,
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
151
|
+
from pygeodesy.interns import NN, _2_, _a12_, _area_, _azi1_, _azi2_, _azi12_, \
|
|
152
|
+
_composite_, _lat1_, _lat2_, _lon1_, _lon2_, \
|
|
153
|
+
_m12_, _M12_, _M21_, _number_, _s12_, _S12_, \
|
|
154
|
+
_UNDER_, _X_, _BAR_ # PYCHOK used!
|
|
153
155
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
154
156
|
from pygeodesy.named import ADict, _NamedBase, _NamedTuple, notImplemented, _Pass
|
|
155
|
-
from pygeodesy.props import deprecated_method, Property_RO
|
|
157
|
+
from pygeodesy.props import deprecated_method, Property_RO, property_ROnce
|
|
156
158
|
from pygeodesy.units import Bearing as _Azi, Degrees as _Deg, Lat, Lon, \
|
|
157
159
|
Meter as _M, Meter2 as _M2, Number_
|
|
158
160
|
from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
@@ -160,7 +162,7 @@ from pygeodesy.utily import atan2d, sincos2d, tand, _unrollon, fabs
|
|
|
160
162
|
# from math import fabs # from .utily
|
|
161
163
|
|
|
162
164
|
__all__ = _ALL_LAZY.karney
|
|
163
|
-
__version__ = '24.
|
|
165
|
+
__version__ = '24.07.16'
|
|
164
166
|
|
|
165
167
|
_K_2_0 = _getenv('PYGEODESY_GEOGRAPHICLIB', _2_) == _2_
|
|
166
168
|
_perimeter_ = 'perimeter'
|
|
@@ -207,39 +209,39 @@ class Area3Tuple(_NamedTuple): # in .geodesicx.gxarea
|
|
|
207
209
|
_Units_ = ( Number_, _M, _M2)
|
|
208
210
|
|
|
209
211
|
|
|
210
|
-
class Caps(object):
|
|
212
|
+
class Caps(object):
|
|
211
213
|
'''(INTERNAL) Overriden by C{Caps} below.
|
|
212
214
|
'''
|
|
213
|
-
EMPTY
|
|
214
|
-
_CAP_1
|
|
215
|
-
_CAP_1p
|
|
216
|
-
_CAP_2
|
|
217
|
-
_CAP_3
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
# _CAP_MASK
|
|
221
|
-
LATITUDE
|
|
222
|
-
LONGITUDE
|
|
223
|
-
AZIMUTH
|
|
224
|
-
DISTANCE
|
|
225
|
-
DISTANCE_IN
|
|
226
|
-
REDUCEDLENGTH
|
|
227
|
-
GEODESICSCALE
|
|
228
|
-
AREA
|
|
229
|
-
|
|
230
|
-
STANDARD
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
LINE_OFF
|
|
241
|
-
|
|
242
|
-
|
|
215
|
+
EMPTY = 0 # formerly aka NONE
|
|
216
|
+
_CAP_1 = 1 << 0 # for goedesici/-w
|
|
217
|
+
_CAP_1p = 1 << 1 # for goedesici/-w
|
|
218
|
+
_CAP_2 = 1 << 2
|
|
219
|
+
_CAP_3 = 1 << 3 # for goedesici/-w
|
|
220
|
+
_CAP_4 = 1 << 4 # for goedesicw
|
|
221
|
+
_CAP_ALL = 0x1F
|
|
222
|
+
# _CAP_MASK = _CAP_ALL
|
|
223
|
+
LATITUDE = 1 << 7 # compute latitude C{lat2}
|
|
224
|
+
LONGITUDE = 1 << 8 | _CAP_3 # compute longitude C{lon2}
|
|
225
|
+
AZIMUTH = 1 << 9 # azimuths C{azi1} and C{azi2}
|
|
226
|
+
DISTANCE = 1 << 10 | _CAP_1 # compute distance C{s12}
|
|
227
|
+
DISTANCE_IN = 1 << 11 | _CAP_1 | _CAP_1p # allow distance C{s12} in Direct
|
|
228
|
+
REDUCEDLENGTH = 1 << 12 | _CAP_1 | _CAP_2 # compute reduced length C{m12}
|
|
229
|
+
GEODESICSCALE = 1 << 13 | _CAP_1 | _CAP_2 # compute geodesic scales C{M12} and C{M21}
|
|
230
|
+
AREA = 1 << 14 | _CAP_4 # compute area C{S12}
|
|
231
|
+
|
|
232
|
+
STANDARD = AZIMUTH | DISTANCE | LATITUDE | LONGITUDE
|
|
233
|
+
|
|
234
|
+
_DIRECT3 = AZIMUTH | LATITUDE | LONGITUDE # for goedesicw only
|
|
235
|
+
_INVERSE3 = AZIMUTH | DISTANCE # for goedesicw only
|
|
236
|
+
_STD = STANDARD # for goedesicw only
|
|
237
|
+
_STD_LINE = _STD | DISTANCE_IN # for goedesici/-w
|
|
238
|
+
|
|
239
|
+
LINE_CAPS = _STD_LINE | REDUCEDLENGTH | GEODESICSCALE # .geodesici only
|
|
240
|
+
LONG_UNROLL = 1 << 15 # unroll C{lon2} in .Direct and .Position
|
|
241
|
+
# = 1 << 16 # unused
|
|
242
|
+
LINE_OFF = 1 << 17 # Line without updates from parent geodesic or rhumb
|
|
243
|
+
REVERSE2 = 1 << 18 # reverse C{azi2}
|
|
244
|
+
ALL = 0x7F80 | _CAP_ALL # without LONG_UNROLL, LINE_OFF, REVERSE2 and _DEBUG_*
|
|
243
245
|
|
|
244
246
|
LATITUDE_LONGITUDE = LATITUDE | LONGITUDE
|
|
245
247
|
LATITUDE_LONGITUDE_AREA = LATITUDE | LONGITUDE | AREA
|
|
@@ -247,35 +249,38 @@ class Caps(object): # PYCHOK
|
|
|
247
249
|
AZIMUTH_DISTANCE = AZIMUTH | DISTANCE
|
|
248
250
|
AZIMUTH_DISTANCE_AREA = AZIMUTH | DISTANCE | AREA
|
|
249
251
|
|
|
250
|
-
|
|
251
|
-
_SALPs_CALPs = 1 << 19 # (INTERNAL) GeodesicExact._GenInverse
|
|
252
|
+
_SALP_CALPs_ = 1 << 19 # (INTERNAL) GeodesicExact._GenInverse
|
|
252
253
|
|
|
253
254
|
_DEBUG_AREA = 1 << 20 # (INTERNAL) include Line details
|
|
254
255
|
_DEBUG_DIRECT = 1 << 21 # (INTERNAL) include Direct details
|
|
255
256
|
_DEBUG_INVERSE = 1 << 22 # (INTERNAL) include Inverse details
|
|
256
257
|
_DEBUG_LINE = 1 << 23 # (INTERNAL) include Line details
|
|
257
258
|
_DEBUG_ALL = _DEBUG_AREA | _DEBUG_DIRECT | _DEBUG_INVERSE | \
|
|
258
|
-
_DEBUG_LINE |
|
|
259
|
+
_DEBUG_LINE | _SALP_CALPs_
|
|
259
260
|
|
|
260
|
-
_OUT_ALL = ALL
|
|
261
|
+
_OUT_ALL = ALL # see geographiclib.geodesiccapabilities.py
|
|
261
262
|
_OUT_MASK = ALL | LONG_UNROLL | REVERSE2 | _DEBUG_ALL
|
|
262
263
|
|
|
263
264
|
_AZIMUTH_LATITUDE_LONGITUDE = AZIMUTH | LATITUDE | LONGITUDE
|
|
265
|
+
_AZIMUTH_LATITUDE_LONG_UNROLL = AZIMUTH | LATITUDE | LONG_UNROLL
|
|
264
266
|
_DEBUG_DIRECT_LINE = _DEBUG_DIRECT | _DEBUG_LINE
|
|
265
267
|
# _DISTANCE_IN_OUT = DISTANCE_IN & _OUT_MASK # == DISTANCE_IN in .gx, .gxline
|
|
266
|
-
_LINE = AZIMUTH | LATITUDE | LONG_UNROLL
|
|
267
268
|
_REDUCEDLENGTH_GEODESICSCALE = REDUCEDLENGTH | GEODESICSCALE
|
|
268
269
|
# _REDUCEDLENGTH_GEODESICSCALE_DISTANCE = REDUCEDLENGTH | GEODESICSCALE | DISTANCE
|
|
269
270
|
|
|
270
|
-
def
|
|
271
|
-
'''
|
|
271
|
+
def items(self):
|
|
272
|
+
'''Yield all I{public} C{Caps} as 2-tuple C{(NAME, mask)}.
|
|
273
|
+
'''
|
|
274
|
+
for n, C in Caps.__class__.__dict__.items():
|
|
275
|
+
if isint(C) and not n.startswith(_UNDER_) \
|
|
276
|
+
and n.replace(_UNDER_, NN).isupper():
|
|
277
|
+
yield n, C
|
|
278
|
+
|
|
279
|
+
def toStr(self, Cask, sep=_BAR_):
|
|
280
|
+
'''Return C{Caps} or an C{outmask} as C{str} or tuple of C{str}s.
|
|
272
281
|
'''
|
|
273
|
-
s =
|
|
274
|
-
|
|
275
|
-
if isint(C) and (Csk & C) and int1s(C) == 1 \
|
|
276
|
-
and (C in (Caps.REVERSE2, Caps._SALPs_CALPs)
|
|
277
|
-
or c.replace(_UNDER_, NN).isupper()):
|
|
278
|
-
s.append(c)
|
|
282
|
+
s = (n for n, C in sorted(Caps.items())
|
|
283
|
+
if C and (Cask & C) == C) # and int1s(C) <= 3
|
|
279
284
|
return sep.join(s) if sep else tuple(s)
|
|
280
285
|
|
|
281
286
|
Caps = Caps() # PYCHOK singleton
|
|
@@ -286,7 +291,7 @@ C{AREA} - compute area C{S12},
|
|
|
286
291
|
|
|
287
292
|
C{AZIMUTH} - include azimuths C{azi1} and C{azi2},
|
|
288
293
|
|
|
289
|
-
C{DISTANCE} - compute distance C{s12},
|
|
294
|
+
C{DISTANCE} - compute distance C{s12} and angular distance C{a12},
|
|
290
295
|
|
|
291
296
|
C{DISTANCE_IN} - allow distance C{s12} in C{.Direct},
|
|
292
297
|
|
|
@@ -310,13 +315,19 @@ and C{ALL} - all of the above.
|
|
|
310
315
|
|
|
311
316
|
C{STANDARD} = C{AZIMUTH | DISTANCE | DISTANCE_IN | LATITUDE | LONGITUDE}'''
|
|
312
317
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
318
|
+
_key2Caps = dict(a12 =Caps.DISTANCE, # in GDict._unCaps
|
|
319
|
+
azi2=Caps.AZIMUTH,
|
|
320
|
+
lat2=Caps.LATITUDE,
|
|
321
|
+
lon2=Caps.LONGITUDE,
|
|
322
|
+
m12 =Caps.REDUCEDLENGTH,
|
|
323
|
+
M12 =Caps.GEODESICSCALE,
|
|
324
|
+
M21 =Caps.GEODESICSCALE,
|
|
325
|
+
s12 =Caps.DISTANCE,
|
|
326
|
+
S12 =Caps.AREA)
|
|
316
327
|
|
|
317
328
|
|
|
318
329
|
class _CapsBase(_NamedBase): # in .auxilats, .geodesicx.gxbases
|
|
319
|
-
'''(INTERNAL) Base class for C{
|
|
330
|
+
'''(INTERNAL) Base class for C{Geodesic*}, C{Geodesic*Exact}, C{Intersectool} and C{Rhumb*Base}.
|
|
320
331
|
'''
|
|
321
332
|
ALL = Caps.ALL
|
|
322
333
|
AREA = Caps.AREA
|
|
@@ -426,6 +437,12 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
426
437
|
'''
|
|
427
438
|
return self._toTuple(Inverse10Tuple, dflt)
|
|
428
439
|
|
|
440
|
+
def _toNAN(self, outmask): # .GeodesicLineExact._GenPosition
|
|
441
|
+
'''(INTERNAL) Convert this C{GDict} to all C{NAN}s.
|
|
442
|
+
'''
|
|
443
|
+
d = dict((n, NAN) for n in GeodSolve12Tuple._Names_)
|
|
444
|
+
return self.set_(**d)._unCaps(outmask)
|
|
445
|
+
|
|
429
446
|
@deprecated_method
|
|
430
447
|
def toRhumb7Tuple(self, dflt=NAN): # PYCHOK no cover
|
|
431
448
|
'''DEPRECATED on 23.12.07, use method C{toRhumb8Tuple}.
|
|
@@ -461,15 +478,40 @@ class GDict(ADict): # XXX _NamedDict
|
|
|
461
478
|
t = tuple(_g(self, n, dflt) for n in nTuple._Names_)
|
|
462
479
|
return nTuple(t, iteration=self._iteration)
|
|
463
480
|
|
|
481
|
+
def _2X(self, gl, _2X=_X_): # .Intersectool, .Intersector
|
|
482
|
+
'''(INTERNAL) Rename C{-2} attr to C{-X} or C{-M}.
|
|
483
|
+
'''
|
|
484
|
+
X = GDict(self)
|
|
485
|
+
for n in (_lat2_, _lon2_, _azi2_, _s12_, _a12_):
|
|
486
|
+
if n in X: # X._X = X._2
|
|
487
|
+
X[n[:-1] + _2X] = X.pop(n)
|
|
488
|
+
v = getattr(gl, n, X)
|
|
489
|
+
if v is not X: # X._2 = gl._2
|
|
490
|
+
X[n] = v
|
|
491
|
+
return X
|
|
492
|
+
|
|
464
493
|
def _unCaps(self, outmask): # in .geodsolve
|
|
465
494
|
'''(INTERNAL) Remove superfluous items.
|
|
466
495
|
'''
|
|
467
|
-
for k,
|
|
468
|
-
if k in self and
|
|
496
|
+
for k, C in _key2Caps.items():
|
|
497
|
+
if k in self and (outmask & C) != C:
|
|
469
498
|
self.pop(k) # delattr(self, k)
|
|
470
499
|
return self
|
|
471
500
|
|
|
472
501
|
|
|
502
|
+
class GeodSolve12Tuple(_GTuple):
|
|
503
|
+
'''12-Tuple C{(lat1, lon1, azi1, lat2, lon2, azi2, s12, a12, m12, M12, M21, S12)} with
|
|
504
|
+
angles C{lat1}, C{lon1}, C{azi1}, C{lat2}, C{lon2} and C{azi2} and arc C{a12} all in
|
|
505
|
+
C{degrees}, initial C{azi1} and final C{azi2} forward azimuths, distance C{s12} and
|
|
506
|
+
reduced length C{m12} in C{meter}, area C{S12} in C{meter} I{squared} and geodesic
|
|
507
|
+
scale factors C{M12} and C{M21}, both C{scalar}, see U{GeodSolve
|
|
508
|
+
<https://GeographicLib.SourceForge.io/C++/doc/GeodSolve.1.html>}.
|
|
509
|
+
'''
|
|
510
|
+
# from GeodSolve --help option -f ... lat1 lon1 azi1 lat2 lon2 azi2 s12 a12 m12 M12 M21 S12
|
|
511
|
+
_Names_ = (_lat1_, _lon1_, _azi1_, _lat2_, _lon2_, _azi2_, _s12_, _a12_, _m12_, _M12_, _M21_, _S12_)
|
|
512
|
+
_Units_ = (_Lat, _Lon, _Azi, _Lat, _Lon, _Azi, _M, _Deg, _Pass, _Pass, _Pass, _M2)
|
|
513
|
+
|
|
514
|
+
|
|
473
515
|
class Inverse10Tuple(_GTuple):
|
|
474
516
|
'''10-Tuple C{(a12, s12, salp1, calp1, salp2, calp2, m12, M12, M21, S12)} with arc length
|
|
475
517
|
C{a12} in C{degrees}, distance C{s12} and reduced length C{m12} in C{meter}, area
|
|
@@ -494,13 +536,13 @@ class _kWrapped(object): # in .geodesicw
|
|
|
494
536
|
<https://PyPI.org/project/geographiclib>} classes.
|
|
495
537
|
'''
|
|
496
538
|
|
|
497
|
-
@
|
|
539
|
+
@property_ROnce
|
|
498
540
|
def geographiclib(self):
|
|
499
541
|
'''Lazily import C{geographiclib}, provided the U{geographiclib
|
|
500
542
|
<https://PyPI.org/project/geographiclib>} package is installed,
|
|
501
543
|
otherwise raise a C{LazyImportError}.
|
|
502
544
|
'''
|
|
503
|
-
g = _xgeographiclib(self.__class__, 1, 49)
|
|
545
|
+
g = _xgeographiclib(self.__class__.__module__, 1, 49)
|
|
504
546
|
from geographiclib.geodesic import Geodesic
|
|
505
547
|
g.Geodesic = Geodesic
|
|
506
548
|
from geographiclib.geodesicline import GeodesicLine
|
|
@@ -509,7 +551,7 @@ class _kWrapped(object): # in .geodesicw
|
|
|
509
551
|
g.Math = Math
|
|
510
552
|
return g
|
|
511
553
|
|
|
512
|
-
@
|
|
554
|
+
@property_ROnce
|
|
513
555
|
def Math(self):
|
|
514
556
|
'''Wrap the C{geomath.Math} class, provided the U{geographiclib
|
|
515
557
|
<https://PyPI.org/project/geographiclib>} package is installed,
|
|
@@ -562,7 +604,7 @@ class Rhumb8Tuple(_GTuple):
|
|
|
562
604
|
|
|
563
605
|
@kwarg dflt: Default value for missing items (C{any}).
|
|
564
606
|
@kwarg a12_m12_M12_M21_salp1_calp1_salp2_calp2: Optional keyword
|
|
565
|
-
|
|
607
|
+
arguments to specify or override L{Inverse10Tuple} items.
|
|
566
608
|
|
|
567
609
|
@return: L{Inverse10Tuple}C{(a12, s12, salp1, calp1, salp2, calp2,
|
|
568
610
|
m12, M12, M21, S12)}.
|
|
@@ -687,6 +729,17 @@ def _isfinite(x): # mimick geomath.Math.isfinite
|
|
|
687
729
|
return _math_isfinite(x) # and fabs(x) <= _MAX
|
|
688
730
|
|
|
689
731
|
|
|
732
|
+
def _llz2gl(gl, **llz2): # see .geodesici._llz2G
|
|
733
|
+
'''(INTERNAL) Set C{gl.lat2, .lon2, .azi2} from C{llz2}.
|
|
734
|
+
'''
|
|
735
|
+
if llz2:
|
|
736
|
+
for n in (_lat2_, _lon2_, _azi2_): # _lat1_, _lon1_, _azi1_
|
|
737
|
+
v = llz2.get(n, None)
|
|
738
|
+
if v is not None:
|
|
739
|
+
setattr(gl, n, v)
|
|
740
|
+
return gl
|
|
741
|
+
|
|
742
|
+
|
|
690
743
|
def _norm2(x, y): # mimick geomath.Math.norm
|
|
691
744
|
'''Normalize C{B{x}} and C{B{y}}.
|
|
692
745
|
|
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.07.16'
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class KTMError(_ValueError):
|
|
@@ -433,10 +433,7 @@ def _cma(a, b0, b1, Cn):
|
|
|
433
433
|
@see: CPython function U{_Py_c_prod<https://GitHub.com/python/
|
|
434
434
|
cpython/blob/main/Objects/complexobject.c>}.
|
|
435
435
|
|
|
436
|
-
@note: Python function C{cmath.fsum} is no longer available
|
|
437
|
-
but stil mentioned in Note 4 of the comments before
|
|
438
|
-
CPython function U{math_fsum<https://GitHub.com/python/
|
|
439
|
-
cpython/blob/main/Modules/mathmodule.c>}
|
|
436
|
+
@note: Python function C{cmath.fsum} is no longer available.
|
|
440
437
|
'''
|
|
441
438
|
r = fsum1f_(a.real * b0.real, -a.imag * b0.imag, -b1.real, Cn)
|
|
442
439
|
j = fsum1f_(a.real * b0.imag, a.imag * b0.real, -b1.imag)
|
pygeodesy/latlonBase.py
CHANGED
|
@@ -41,7 +41,7 @@ from pygeodesy.namedTuples import Bounds2Tuple, LatLon2Tuple, PhiLam2Tuple, \
|
|
|
41
41
|
Trilaterate5Tuple
|
|
42
42
|
# from pygeodesy.nvectorBase import _N_vector_ # _MODS
|
|
43
43
|
from pygeodesy.props import deprecated_method, Property, Property_RO, \
|
|
44
|
-
property_RO, _update_all
|
|
44
|
+
property_RO, property_ROnce, _update_all
|
|
45
45
|
# from pygeodesy.streprs import Fmt, hstr # from .named, _MODS
|
|
46
46
|
from pygeodesy.units import _isDegrees, _isRadius, Distance_, Lat, Lon, \
|
|
47
47
|
Height, Radius, Radius_, Scalar, Scalar_
|
|
@@ -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.07.12'
|
|
58
58
|
|
|
59
59
|
_formy = _MODS.into(formy=__name__)
|
|
60
60
|
|
|
@@ -475,12 +475,11 @@ class LatLonBase(_NamedBase):
|
|
|
475
475
|
r = func_(phi2, self.phi, lam21, datum=D)
|
|
476
476
|
return r * (D.ellipsoid.a if radius is None else radius)
|
|
477
477
|
|
|
478
|
-
@
|
|
478
|
+
@property_ROnce
|
|
479
479
|
def Ecef(self):
|
|
480
480
|
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
481
481
|
'''
|
|
482
|
-
|
|
483
|
-
return E
|
|
482
|
+
return _MODS.ecef.EcefKarney
|
|
484
483
|
|
|
485
484
|
@Property_RO
|
|
486
485
|
def _Ecef_forward(self):
|
pygeodesy/lazily.py
CHANGED
|
@@ -48,26 +48,27 @@ except ImportError as x: # Python 2.6-
|
|
|
48
48
|
from os import getenv as _getenv
|
|
49
49
|
# import sys as _sys # from .interns
|
|
50
50
|
|
|
51
|
-
__as__
|
|
52
|
-
_dunder_all_
|
|
53
|
-
_enabled_
|
|
54
|
-
_FOR_DOCS
|
|
55
|
-
_i0
|
|
56
|
-
_init__all__
|
|
57
|
-
_lazily_
|
|
58
|
-
_lazily_imported_
|
|
59
|
-
_PYGEODESY_GEOCONVERT_
|
|
60
|
-
_PYGEODESY_GEODSOLVE_
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
51
|
+
__as__ = ' as '
|
|
52
|
+
_dunder_all_ = '__all__' # in .__main__
|
|
53
|
+
_enabled_ = 'enabled'
|
|
54
|
+
_FOR_DOCS = _getenv('PYGEODESY_FOR_DOCS', NN) # for epydoc ...
|
|
55
|
+
_i0 = () # PYCHOK empty tuple
|
|
56
|
+
_init__all__ = _FOR_DOCS or _getenv('PYGEODESY_INIT__ALL__', _dunder_all_) == _dunder_all_ # PYCHOK exported
|
|
57
|
+
_lazily_ = 'lazily'
|
|
58
|
+
_lazily_imported_ = _SPACE_(_HASH_, _lazily_, 'imported')
|
|
59
|
+
_PYGEODESY_GEOCONVERT_ = 'PYGEODESY_GEOCONVERT' # PYCHOK .mgrs, test.bases
|
|
60
|
+
_PYGEODESY_GEODSOLVE_ = 'PYGEODESY_GEODSOLVE' # PYCHOK .geodsolve, test.bases
|
|
61
|
+
_PYGEODESY_INTERSECTTOOL_ = 'PYGEODESY_INTERSECTTOOL' # PYCHOK .intersectool, test.bases
|
|
62
|
+
_PYGEODESY_LAZY_IMPORT_ = 'PYGEODESY_LAZY_IMPORT'
|
|
63
|
+
_PYGEODESY_RHUMBSOLVE_ = 'PYGEODESY_RHUMBSOLVE' # PYCHOK .rhumb.solve, test.bases
|
|
64
|
+
_PYTHON_X_DEV = getattr(_sys, '_xoptions', {}).get('dev', # Python 3.2+
|
|
64
65
|
_getenv('PYTHONDEVMODE', NN)) # PYCHOK exported
|
|
65
|
-
_sys_version_info2
|
|
66
|
-
_unlazy = _unLazy0
|
|
67
|
-
_WARNINGS_X_DEV
|
|
68
|
-
|
|
66
|
+
_sys_version_info2 = _sys.version_info[:2] # in .basics, .fmath, ...
|
|
67
|
+
_unlazy = _unLazy0 = _isfrozen or _sys_version_info2 < (3, 7) # PYCHOK mod.__getattr__ 3.7+
|
|
68
|
+
_WARNINGS_X_DEV = _getenv('PYGEODESY_WARNINGS', NN) and (
|
|
69
|
+
_PYTHON_X_DEV or bool(_sys.warnoptions)) # PYCHOK .props
|
|
69
70
|
# @module_property[_RO?] <https://GitHub.com/jtushman/proxy_tools/>
|
|
70
|
-
isLazy
|
|
71
|
+
isLazy = None # see @var isLazy in .__init__
|
|
71
72
|
|
|
72
73
|
|
|
73
74
|
class LazyAttributeError(AttributeError):
|
|
@@ -283,7 +284,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
283
284
|
fsums=_i('Fsum', 'DivMod2Tuple', 'Fsum2Tuple', 'ResidualError',
|
|
284
285
|
'fsum', 'fsum_', 'fsumf_', 'fsum1', 'fsum1_', 'fsum1f_'),
|
|
285
286
|
gars=_i('Garef', 'GARSError'),
|
|
286
|
-
geodesici=_i('
|
|
287
|
+
geodesici=_i('Intersectool', 'Intersectool5Tuple', 'Intersect7Tuple',
|
|
288
|
+
'Intersector', 'Intersector5Tuple', 'Middle5Tuple', 'XDict'),
|
|
287
289
|
geodesicw=_i('Geodesic', 'GeodesicLine', 'Geodesic_WGS84'),
|
|
288
290
|
geodesicx=_i('gx', 'gxarea', 'gxbases', 'gxline', # modules
|
|
289
291
|
'GeodesicAreaExact', 'GeodesicExact', 'GeodesicLineExact', 'PolygonArea'),
|
|
@@ -341,7 +343,8 @@ _ALL_LAZY = _NamedEnum_RO(_name='_ALL_LAZY',
|
|
|
341
343
|
'areaOf', 'boundsOf', 'centroidOf', 'fractional',
|
|
342
344
|
'isclockwise', 'isconvex', 'isconvex_', 'isenclosedBy', 'ispolar',
|
|
343
345
|
'luneOf', 'nearestOn5', 'perimeterOf', 'quadOf'),
|
|
344
|
-
props=_i('Property', 'Property_RO', '
|
|
346
|
+
props=_i('Property', 'Property_RO', 'property_doc_',
|
|
347
|
+
'property_RO', 'property_ROnce', 'property_ROver',
|
|
345
348
|
'deprecated_class', 'deprecated_function', 'deprecated_method',
|
|
346
349
|
'deprecated_Property_RO', 'deprecated_property_RO', 'DeprecationWarnings'),
|
|
347
350
|
resections=_i('Collins5Tuple', 'ResectionError', 'Survey3Tuple', 'Tienstra7Tuple',
|
|
@@ -409,7 +412,7 @@ _ALL_DEPRECATED = _NamedEnum_RO(_name='_ALL_DEPRECATED',
|
|
|
409
412
|
'HeightIDW', 'HeightIDW2', 'HeightIDW3', 'Helmert7Tuple',
|
|
410
413
|
'Lam_', 'LatLonExact4Tuple', 'NearestOn4Tuple', 'Ned3Tuple',
|
|
411
414
|
'Phi_', 'RefFrameError', 'Rhumb7Tuple', 'RhumbOrder2Tuple',
|
|
412
|
-
'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple'),
|
|
415
|
+
'Transform7Tuple', 'TriAngle4Tuple', 'UtmUps4Tuple', 'XDist'),
|
|
413
416
|
deprecated_consterns=_i('EPS1_2', 'MANTIS', 'OK'),
|
|
414
417
|
deprecated_datum=_i('Curvature2Tuple', 'Datum', 'Ellipsoid', 'Transform', # assert
|
|
415
418
|
'Datums', 'Ellipsoids', 'Transforms',
|
|
@@ -519,7 +522,7 @@ class _ALL_MODS(_internals._MODS_Base):
|
|
|
519
522
|
_internals._MODS = _ALL_MODS = _ALL_MODS() # PYCHOK singleton
|
|
520
523
|
|
|
521
524
|
__all__ = _ALL_LAZY.lazily
|
|
522
|
-
__version__ = '24.
|
|
525
|
+
__version__ = '24.07.18'
|
|
523
526
|
|
|
524
527
|
|
|
525
528
|
def _ALL_OTHER(*objs):
|
pygeodesy/ltp.py
CHANGED
|
@@ -33,8 +33,8 @@ from pygeodesy.ltpTuples import Attitude4Tuple, ChLVEN2Tuple, ChLV9Tuple, \
|
|
|
33
33
|
ChLVyx2Tuple, _XyzLocals4, _XyzLocals5, Xyz4Tuple
|
|
34
34
|
from pygeodesy.named import _name__, _name2__, _NamedBase, notOverloaded
|
|
35
35
|
from pygeodesy.namedTuples import LatLon3Tuple, LatLon4Tuple, Vector3Tuple
|
|
36
|
-
from pygeodesy.props import Property, Property_RO, property_doc_,
|
|
37
|
-
|
|
36
|
+
from pygeodesy.props import Property, Property_RO, property_doc_, \
|
|
37
|
+
property_ROver, _update_all
|
|
38
38
|
from pygeodesy.streprs import Fmt, strs, unstr
|
|
39
39
|
from pygeodesy.units import Bearing, Degrees, _isHeight, Meter
|
|
40
40
|
from pygeodesy.utily import cotd, _loneg, sincos2d, sincos2d_, tand, tand_, \
|
|
@@ -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.07.12'
|
|
48
48
|
|
|
49
49
|
_height0_ = _height_ + _0_
|
|
50
50
|
_narrow_ = 'narrow'
|
|
@@ -722,15 +722,15 @@ class _ChLV(object):
|
|
|
722
722
|
t = Y_X_h_lat_lon_h + (self, self._t0, None) # PYCHOK _t0
|
|
723
723
|
return ChLV9Tuple(t, name=name)
|
|
724
724
|
|
|
725
|
-
@
|
|
725
|
+
@property_ROver
|
|
726
726
|
def _enh_n_h(self):
|
|
727
727
|
'''(INTERNAL) Get C{ChLV*.reverse} args[1:4] names, I{once}.
|
|
728
728
|
'''
|
|
729
|
-
|
|
729
|
+
t = _args_kwds_names(_ChLV.reverse)[1:4]
|
|
730
730
|
# assert _args_kwds_names( ChLV.reverse)[1:4] == t
|
|
731
731
|
# assert _args_kwds_names(ChLVa.reverse)[1:4] == t
|
|
732
732
|
# assert _args_kwds_names(ChLVe.reverse)[1:4] == t
|
|
733
|
-
return t
|
|
733
|
+
return t # overwrite propertyROver
|
|
734
734
|
|
|
735
735
|
def forward(self, latlonh, lon=None, height=0, M=None, **name): # PYCHOK no cover
|
|
736
736
|
'''Convert WGS84 geodetic to I{Swiss} projection coordinates. I{Must be overloaded}.
|
pygeodesy/ltpTuples.py
CHANGED
|
@@ -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.06.
|
|
39
|
+
__version__ = '24.06.28'
|
|
40
40
|
|
|
41
41
|
_aer_ = 'aer'
|
|
42
42
|
_alt_ = 'alt'
|
|
@@ -349,7 +349,7 @@ class Aer(_AbcBase):
|
|
|
349
349
|
number of (decimal) digits, unstripped
|
|
350
350
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
351
351
|
backets format (C{str}) and separator
|
|
352
|
-
C{B{sep}=
|
|
352
|
+
C{B{sep}=", "} to join (C{str}).
|
|
353
353
|
|
|
354
354
|
@return: This AER as "[degrees360, degrees90, meter]" (C{str}).
|
|
355
355
|
'''
|
|
@@ -572,7 +572,7 @@ class Ned(_AbcBase):
|
|
|
572
572
|
number of (decimal) digits, unstripped
|
|
573
573
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
574
574
|
backets format (C{str}) and separator
|
|
575
|
-
C{B{sep}=
|
|
575
|
+
C{B{sep}=", "} to join (C{str}).
|
|
576
576
|
|
|
577
577
|
@return: This NED as "[meter, meter, meter]" (C{str}).
|
|
578
578
|
'''
|
|
@@ -659,7 +659,7 @@ class _Vector3d(Vector3d):
|
|
|
659
659
|
number of (decimal) digits, unstripped
|
|
660
660
|
(C{int}), C{B{fmt}='[]'} the enclosing
|
|
661
661
|
backets format (C{str}) and separator
|
|
662
|
-
C{B{sep}=
|
|
662
|
+
C{B{sep}=", "} to join (C{str}).
|
|
663
663
|
|
|
664
664
|
@return: This XYZ as "[meter, meter, meter]" (C{str}).
|
|
665
665
|
'''
|
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.07.12'
|
|
38
38
|
|
|
39
39
|
_COMMANL_ = _COMMA_ + _NL_
|
|
40
40
|
_COMMASPACEDOT_ = _COMMASPACE_ + _DOT_
|
|
@@ -1231,9 +1231,9 @@ def modulename(clas, prefixed=None): # in .basics._xversion
|
|
|
1231
1231
|
@return: The B{C{class}}'s C{[module.]class} name (C{str}).
|
|
1232
1232
|
'''
|
|
1233
1233
|
try:
|
|
1234
|
-
n =
|
|
1234
|
+
n = clas.__name__
|
|
1235
1235
|
except AttributeError:
|
|
1236
|
-
n = _dunder_name_
|
|
1236
|
+
n = clas if isstr(clas) else _dunder_name_
|
|
1237
1237
|
if prefixed or (classnaming() if prefixed is None else False):
|
|
1238
1238
|
try:
|
|
1239
1239
|
m = clas.__module__.rsplit(_DOT_, 1)
|
pygeodesy/nvectorBase.py
CHANGED
|
@@ -29,7 +29,7 @@ from pygeodesy.named import _xother3, _under
|
|
|
29
29
|
from pygeodesy.namedTuples import Trilaterate5Tuple, Vector3Tuple, \
|
|
30
30
|
Vector4Tuple, map1
|
|
31
31
|
from pygeodesy.props import deprecated_method, Property_RO, property_doc_, \
|
|
32
|
-
property_RO, _update_all
|
|
32
|
+
property_RO, property_ROnce, _update_all
|
|
33
33
|
from pygeodesy.streprs import Fmt, hstr, unstr
|
|
34
34
|
from pygeodesy.units import Bearing, Height, Radius_, Scalar
|
|
35
35
|
from pygeodesy.utily import sincos2d, _unrollon, _unrollon3
|
|
@@ -38,7 +38,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
|
38
38
|
from math import fabs, sqrt
|
|
39
39
|
|
|
40
40
|
__all__ = _ALL_LAZY.nvectorBase
|
|
41
|
-
__version__ = '24.
|
|
41
|
+
__version__ = '24.07.12'
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class NvectorBase(Vector3d): # XXX kept private
|
|
@@ -78,12 +78,11 @@ class NvectorBase(Vector3d): # XXX kept private
|
|
|
78
78
|
'''
|
|
79
79
|
return self._datum
|
|
80
80
|
|
|
81
|
-
@
|
|
81
|
+
@property_ROnce
|
|
82
82
|
def Ecef(self):
|
|
83
83
|
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
84
84
|
'''
|
|
85
|
-
|
|
86
|
-
return E
|
|
85
|
+
return _MODS.ecef.EcefKarney
|
|
87
86
|
|
|
88
87
|
@property_RO
|
|
89
88
|
def ellipsoidalNvector(self):
|