pygeodesy 24.7.7__py2.py3-none-any.whl → 24.8.4__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.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/METADATA +28 -26
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/RECORD +39 -39
- pygeodesy/__init__.py +50 -51
- pygeodesy/auxilats/auxAngle.py +5 -5
- pygeodesy/auxilats/auxDST.py +9 -10
- pygeodesy/auxilats/auxily.py +2 -2
- pygeodesy/azimuthal.py +4 -4
- pygeodesy/cartesianBase.py +6 -7
- pygeodesy/css.py +5 -5
- pygeodesy/ecef.py +7 -9
- pygeodesy/ellipsoids.py +12 -12
- pygeodesy/formy.py +2 -2
- pygeodesy/fsums.py +12 -6
- pygeodesy/gars.py +59 -52
- pygeodesy/geodesici.py +232 -137
- pygeodesy/geodesicw.py +70 -45
- pygeodesy/geodesicx/gx.py +8 -8
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +12 -3
- pygeodesy/geohash.py +484 -267
- pygeodesy/geoids.py +13 -11
- pygeodesy/heights.py +30 -40
- pygeodesy/internals.py +19 -6
- pygeodesy/karney.py +85 -79
- pygeodesy/ktm.py +2 -5
- pygeodesy/latlonBase.py +5 -6
- pygeodesy/lazily.py +21 -19
- pygeodesy/ltp.py +6 -6
- pygeodesy/ltpTuples.py +6 -6
- pygeodesy/named.py +3 -3
- pygeodesy/nvectorBase.py +4 -5
- pygeodesy/props.py +75 -17
- pygeodesy/rhumb/solve.py +2 -2
- pygeodesy/solveBase.py +26 -12
- pygeodesy/triaxials.py +6 -7
- pygeodesy/units.py +34 -17
- pygeodesy/wgrs.py +93 -83
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.7.7.dist-info → PyGeodesy-24.8.4.dist-info}/top_level.txt +0 -0
pygeodesy/cartesianBase.py
CHANGED
|
@@ -28,8 +28,8 @@ from pygeodesy.named import _name2__, _Pass
|
|
|
28
28
|
from pygeodesy.namedTuples import LatLon4Tuple, _NamedTupleTo , Vector3Tuple, \
|
|
29
29
|
Vector4Tuple, Bearing2Tuple # PYCHOK .sphericalBase
|
|
30
30
|
# from pygeodesy.nvectorBase import _N_vector # _MODS
|
|
31
|
-
from pygeodesy.props import deprecated_method, Property, Property_RO, \
|
|
32
|
-
|
|
31
|
+
from pygeodesy.props import deprecated_method, Property, Property_RO, property_doc_, \
|
|
32
|
+
property_RO, property_ROnce, _update_all
|
|
33
33
|
# from pygeodesy,resections import cassini, collins5, pierlot, pierlotx, \
|
|
34
34
|
# tienstra7 # _MODS
|
|
35
35
|
# from pygeodesy.streprs import Fmt # from .fsums
|
|
@@ -43,7 +43,7 @@ from pygeodesy.vector3d import Vector3d, _xyzhdlln4
|
|
|
43
43
|
# from math import atan2, degrees, fabs, radians, sqrt # from .fmath, .utily
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.cartesianBase
|
|
46
|
-
__version__ = '24.
|
|
46
|
+
__version__ = '24.07.29'
|
|
47
47
|
|
|
48
48
|
_r_ = 'r'
|
|
49
49
|
_theta_ = 'theta'
|
|
@@ -211,12 +211,11 @@ class CartesianBase(Vector3d):
|
|
|
211
211
|
r = Cartesian(*c, **kwds)
|
|
212
212
|
return r.renamed(n) if n else r
|
|
213
213
|
|
|
214
|
-
@
|
|
214
|
+
@property_ROnce
|
|
215
215
|
def Ecef(self):
|
|
216
216
|
'''Get the ECEF I{class} (L{EcefKarney}), I{once}.
|
|
217
217
|
'''
|
|
218
|
-
|
|
219
|
-
return E
|
|
218
|
+
return _MODS.ecef.EcefKarney
|
|
220
219
|
|
|
221
220
|
@Property_RO
|
|
222
221
|
def _ecef9(self):
|
|
@@ -301,7 +300,7 @@ class CartesianBase(Vector3d):
|
|
|
301
300
|
coordinates I{at height} in C{meter}, conventionally.
|
|
302
301
|
|
|
303
302
|
@note: This cartesian's coordinates are returned if B{C{earth}} and this
|
|
304
|
-
datum or B{C{
|
|
303
|
+
datum or B{C{height}} and/or this height are C{None} or undefined.
|
|
305
304
|
|
|
306
305
|
@note: Include keyword argument C{B{datum}=None} if class B{C{Cartesian}}
|
|
307
306
|
does not accept a B{C{datum}} keyword agument.
|
pygeodesy/css.py
CHANGED
|
@@ -27,13 +27,13 @@ from pygeodesy.namedTuples import EasNor2Tuple, EasNor3Tuple, \
|
|
|
27
27
|
from pygeodesy.props import deprecated_Property_RO, Property, \
|
|
28
28
|
Property_RO, _update_all
|
|
29
29
|
from pygeodesy.streprs import Fmt, _fstrENH2, _fstrLL0, _xzipairs
|
|
30
|
-
from pygeodesy.units import
|
|
30
|
+
from pygeodesy.units import Azimuth, Degrees, Easting, Height, _heigHt, \
|
|
31
31
|
Lat_, Lon_, Northing, Scalar
|
|
32
32
|
|
|
33
33
|
# from math import fabs # from .karney
|
|
34
34
|
|
|
35
35
|
__all__ = _ALL_LAZY.css
|
|
36
|
-
__version__ = '24.
|
|
36
|
+
__version__ = '24.07.25'
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def _CS0(cs0):
|
|
@@ -578,7 +578,7 @@ class EasNorAziRk4Tuple(_NamedTuple):
|
|
|
578
578
|
C{reciprocal} of azimuthal northing scale, both in C{degrees}.
|
|
579
579
|
'''
|
|
580
580
|
_Names_ = (_easting_, _northing_, _azimuth_, _reciprocal_)
|
|
581
|
-
_Units_ = ( Easting, Northing,
|
|
581
|
+
_Units_ = ( Easting, Northing, Azimuth, Scalar)
|
|
582
582
|
|
|
583
583
|
|
|
584
584
|
class EasNorAziRkEqu6Tuple(_NamedTuple):
|
|
@@ -589,7 +589,7 @@ class EasNorAziRkEqu6Tuple(_NamedTuple):
|
|
|
589
589
|
C{equatorarc} and C{equatorazimuth}, all in C{degrees}.
|
|
590
590
|
'''
|
|
591
591
|
_Names_ = EasNorAziRk4Tuple._Names_ + ('equatorarc', 'equatorazimuth')
|
|
592
|
-
_Units_ = EasNorAziRk4Tuple._Units_ + ( Degrees,
|
|
592
|
+
_Units_ = EasNorAziRk4Tuple._Units_ + ( Degrees, Azimuth)
|
|
593
593
|
|
|
594
594
|
|
|
595
595
|
class LatLonAziRk4Tuple(_NamedTuple):
|
|
@@ -598,7 +598,7 @@ class LatLonAziRk4Tuple(_NamedTuple):
|
|
|
598
598
|
C{reciprocal} the reciprocal of azimuthal northing scale.
|
|
599
599
|
'''
|
|
600
600
|
_Names_ = (_lat_, _lon_, _azimuth_, _reciprocal_)
|
|
601
|
-
_Units_ = ( Lat_, Lon_,
|
|
601
|
+
_Units_ = ( Lat_, Lon_, Azimuth, Scalar)
|
|
602
602
|
|
|
603
603
|
|
|
604
604
|
def toCss(latlon, cs0=None, height=None, Css=Css, **name):
|
pygeodesy/ecef.py
CHANGED
|
@@ -76,7 +76,7 @@ from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
|
76
76
|
from pygeodesy.named import _name__, _name1__, _NamedBase, _NamedTuple, _Pass, _xnamed
|
|
77
77
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLon3Tuple, \
|
|
78
78
|
PhiLam2Tuple, Vector3Tuple, Vector4Tuple
|
|
79
|
-
from pygeodesy.props import deprecated_method, Property_RO,
|
|
79
|
+
from pygeodesy.props import deprecated_method, Property_RO, property_ROver, property_doc_
|
|
80
80
|
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
81
81
|
from pygeodesy.units import _isRadius, Degrees, Height, Int, Lam, Lat, Lon, Meter, \
|
|
82
82
|
Phi, Scalar, Scalar_
|
|
@@ -86,7 +86,7 @@ from pygeodesy.utily import atan1, atan1d, atan2d, degrees90, degrees180, \
|
|
|
86
86
|
from math import atan2, cos, degrees, fabs, radians, sqrt
|
|
87
87
|
|
|
88
88
|
__all__ = _ALL_LAZY.ecef
|
|
89
|
-
__version__ = '24.06.
|
|
89
|
+
__version__ = '24.06.12'
|
|
90
90
|
|
|
91
91
|
_Ecef_ = 'Ecef'
|
|
92
92
|
_prolate_ = 'prolate'
|
|
@@ -261,13 +261,12 @@ class _EcefBase(_NamedBase):
|
|
|
261
261
|
raise EcefError(phi=phi, lam=lam, height=height, cause=x)
|
|
262
262
|
return self._forward(*plhn, M=M, _philam=True)
|
|
263
263
|
|
|
264
|
-
@
|
|
264
|
+
@property_ROver
|
|
265
265
|
def _Geocentrics(self):
|
|
266
266
|
'''(INTERNAL) Get the valid geocentric classes. I{once}.
|
|
267
267
|
'''
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
return t
|
|
268
|
+
return (Ecef9Tuple, # overwrite property_ROver
|
|
269
|
+
_MODS.cartesianBase.CartesianBase)
|
|
271
270
|
|
|
272
271
|
@Property_RO
|
|
273
272
|
def _isYou(self):
|
|
@@ -1028,12 +1027,11 @@ class Ecef9Tuple(_NamedTuple):
|
|
|
1028
1027
|
_Names_ = (_x_, _y_, _z_, _lat_, _lon_, _height_, _C_, _M_, _datum_)
|
|
1029
1028
|
_Units_ = ( Meter, Meter, Meter, Lat, Lon, Height, Int, _Pass, _Pass)
|
|
1030
1029
|
|
|
1031
|
-
@
|
|
1030
|
+
@property_ROver
|
|
1032
1031
|
def _CartesianBase(self):
|
|
1033
1032
|
'''(INTERNAL) Get class C{CartesianBase}, I{once}.
|
|
1034
1033
|
'''
|
|
1035
|
-
|
|
1036
|
-
return C
|
|
1034
|
+
return _MODS.cartesianBase.CartesianBase # overwrite property_ROver
|
|
1037
1035
|
|
|
1038
1036
|
@deprecated_method
|
|
1039
1037
|
def convertDatum(self, datum2): # for backward compatibility
|
pygeodesy/ellipsoids.py
CHANGED
|
@@ -83,7 +83,7 @@ from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, \
|
|
|
83
83
|
_NamedEnumItem, _NamedTuple, _Pass, _ALL_LAZY, _MODS
|
|
84
84
|
from pygeodesy.namedTuples import Distance2Tuple, Vector3Tuple, Vector4Tuple
|
|
85
85
|
from pygeodesy.props import deprecated_Property_RO, Property_RO, property_doc_, \
|
|
86
|
-
deprecated_property_RO, property_RO
|
|
86
|
+
deprecated_property_RO, property_RO, property_ROver
|
|
87
87
|
from pygeodesy.streprs import Fmt, fstr, instr, strs, unstr
|
|
88
88
|
# from pygeodesy.triaxials import _hartzell3 # _MODS
|
|
89
89
|
from pygeodesy.units import Bearing_, Distance, Float, Float_, Height, Lamd, Lat, Meter, \
|
|
@@ -93,7 +93,7 @@ from pygeodesy.utily import atan1, atan1d, atan2b, degrees90, m2radians, radians
|
|
|
93
93
|
from math import asinh, atan, atanh, cos, degrees, exp, fabs, radians, sin, sinh, sqrt, tan
|
|
94
94
|
|
|
95
95
|
__all__ = _ALL_LAZY.ellipsoids
|
|
96
|
-
__version__ = '24.
|
|
96
|
+
__version__ = '24.07.25'
|
|
97
97
|
|
|
98
98
|
_f_0_0 = Float(f =_0_0) # zero flattening
|
|
99
99
|
_f__0_0 = Float(f_=_0_0) # zero inverse flattening
|
|
@@ -1029,17 +1029,18 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1029
1029
|
raise _ValueError(exact=g, ellipsoid=E, txt_not_=self.name)
|
|
1030
1030
|
return g
|
|
1031
1031
|
|
|
1032
|
-
@
|
|
1032
|
+
@property_ROver
|
|
1033
1033
|
def _Geodesics(self):
|
|
1034
1034
|
'''(INTERNAL) Get all C{Geodesic...} classes, I{once}.
|
|
1035
1035
|
'''
|
|
1036
|
+
t = (_MODS.geodesicx.GeodesicExact,
|
|
1037
|
+
_MODS.geodsolve.GeodesicSolve)
|
|
1036
1038
|
try:
|
|
1037
|
-
t
|
|
1039
|
+
t += (_MODS.geodesicw.Geodesic,
|
|
1040
|
+
_MODS.geodesicw._wrapped.Geodesic)
|
|
1038
1041
|
except ImportError:
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
_MODS.geodsolve.GeodesicSolve) + t
|
|
1042
|
-
return t
|
|
1042
|
+
pass
|
|
1043
|
+
return t # overwrite property_ROver
|
|
1043
1044
|
|
|
1044
1045
|
@property_RO
|
|
1045
1046
|
def geodesicw(self):
|
|
@@ -1517,14 +1518,13 @@ class Ellipsoid(_NamedEnumItem):
|
|
|
1517
1518
|
# raise _IsnotError(_ellipsoidal_, ellipsoid=self)
|
|
1518
1519
|
return _MODS.rhumb.ekx.Rhumb(self, name=self.name)
|
|
1519
1520
|
|
|
1520
|
-
@
|
|
1521
|
+
@property_ROver
|
|
1521
1522
|
def _Rhumbs(self):
|
|
1522
1523
|
'''(INTERNAL) Get all C{Rhumb...} classes, I{once}.
|
|
1523
1524
|
'''
|
|
1524
1525
|
p = _MODS.rhumb
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
return t
|
|
1526
|
+
return (p.aux_.RhumbAux, # overwrite property_ROver
|
|
1527
|
+
p.ekx.Rhumb, p.solve.RhumbSolve)
|
|
1528
1528
|
|
|
1529
1529
|
@property
|
|
1530
1530
|
def rhumbsolve(self):
|
pygeodesy/formy.py
CHANGED
|
@@ -42,7 +42,7 @@ from contextlib import contextmanager
|
|
|
42
42
|
from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
|
|
43
43
|
|
|
44
44
|
__all__ = _ALL_LAZY.formy
|
|
45
|
-
__version__ = '24.
|
|
45
|
+
__version__ = '24.07.29'
|
|
46
46
|
|
|
47
47
|
_RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
|
|
48
48
|
_ratio_ = 'ratio'
|
|
@@ -962,7 +962,7 @@ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
|
|
|
962
962
|
B{C{datum}} if different and to convert from B{C{earth}}.
|
|
963
963
|
|
|
964
964
|
@return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or the
|
|
965
|
-
given B{C{LatLon}} instance) with attribute C{
|
|
965
|
+
given B{C{LatLon}} instance) with attribute C{height} set to the
|
|
966
966
|
distance to the B{C{pov}}.
|
|
967
967
|
|
|
968
968
|
@raise IntersectionError: Invalid B{C{pov}} or B{C{pov}} inside the earth or
|
pygeodesy/fsums.py
CHANGED
|
@@ -273,11 +273,17 @@ def _stresidual(prefix, residual, R=0, **mod_ratio):
|
|
|
273
273
|
def _2sum(a, b): # by .testFmath
|
|
274
274
|
'''(INTERNAL) Return C{a + b} as 2-tuple (sum, residual).
|
|
275
275
|
'''
|
|
276
|
+
# Neumaier, A. U{Rundungsfehleranalyse einiger Verfahren zur Summation endlicher
|
|
277
|
+
# Summen<https://OnlineLibrary.Wiley.com/doi/epdf/10.1002/zamm.19740540106>},
|
|
278
|
+
# 1974, Zeitschrift für Angewandte Mathmatik und Mechanik, vol 51, nr 1, p 39-51
|
|
279
|
+
# <https://StackOverflow.com/questions/78633770/can-neumaier-summation-be-sped-up>
|
|
276
280
|
s = a + b
|
|
277
281
|
if _isfinite(s):
|
|
278
282
|
if fabs(a) < fabs(b):
|
|
279
|
-
b
|
|
280
|
-
|
|
283
|
+
r = (b - s) + a
|
|
284
|
+
else:
|
|
285
|
+
r = (a - s) + b
|
|
286
|
+
return s, r
|
|
281
287
|
u = unstr(_2sum, a, b)
|
|
282
288
|
t = Fmt.PARENSPACED(_not_finite_, s)
|
|
283
289
|
raise _OverflowError(u, txt=t)
|
|
@@ -1909,10 +1915,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase
|
|
|
1909
1915
|
|
|
1910
1916
|
@raise ResidualError: Invalid B{C{threshold}}.
|
|
1911
1917
|
|
|
1912
|
-
@note: L{ResidualError}s may be thrown if the non-zero I{ratio}
|
|
1913
|
-
C{residual / fsum} exceeds the given B{C{threshold}} and
|
|
1914
|
-
|
|
1915
|
-
C{fsum}, i.e. C{(fsum + residual) != fsum} and
|
|
1918
|
+
@note: L{ResidualError}s may be thrown if (1) the non-zero I{ratio}
|
|
1919
|
+
C{residual / fsum} exceeds the given B{C{threshold}} and (2)
|
|
1920
|
+
the C{residual} is non-zero and (3) I{significant} vs the
|
|
1921
|
+
C{fsum}, i.e. C{(fsum + residual) != fsum} and (4) optional
|
|
1916
1922
|
keyword argument C{raiser=False} is missing. Specify a
|
|
1917
1923
|
negative B{C{threshold}} for only non-zero C{residual}
|
|
1918
1924
|
testing without I{significant}.
|
pygeodesy/gars.py
CHANGED
|
@@ -3,33 +3,33 @@
|
|
|
3
3
|
|
|
4
4
|
u'''I{Global Area Reference System} (GARS) en-/decoding.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Transcoded from C++ class U{GARS
|
|
10
|
-
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GARS.html>}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<https://
|
|
6
|
+
Class L{Garef} and several functions to encode, decode and inspect
|
|
7
|
+
GARS references.
|
|
8
|
+
|
|
9
|
+
Transcoded from I{Charles Karney}'s C++ class U{GARS
|
|
10
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1GARS.html>}.
|
|
11
|
+
|
|
12
|
+
@see: U{Global Area Reference System
|
|
13
|
+
<https://WikiPedia.org/wiki/Global_Area_Reference_System>} and U{NGA
|
|
14
|
+
(GARS)<https://Earth-Info.NGA.mil/GandG/coordsys/grids/gars.html>}.
|
|
14
15
|
'''
|
|
15
16
|
|
|
16
17
|
# from pygeodesy.basics import isstr # from .named
|
|
17
18
|
from pygeodesy.constants import _off90, _1_over, _0_5, \
|
|
18
19
|
_1_0 # PYCHOK used!
|
|
19
|
-
from pygeodesy.dms import parse3llh, Fmt # parseDMS2
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xkwds, _xStrError
|
|
21
|
-
from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _COMMA_
|
|
21
|
+
from pygeodesy.interns import NN, _0to9_, _AtoZnoIO_, _COMMA_, _SPACE_
|
|
22
22
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER
|
|
23
|
-
from pygeodesy.named import _name__, isstr, Property_RO
|
|
23
|
+
from pygeodesy.named import _name__, Fmt, isstr, Property_RO
|
|
24
24
|
from pygeodesy.namedTuples import LatLon2Tuple, LatLonPrec3Tuple
|
|
25
25
|
# from pygeodesy.props import Property_RO # from .named
|
|
26
|
-
# from pygeodesy.streprs import Fmt # from .
|
|
26
|
+
# from pygeodesy.streprs import Fmt # from .named
|
|
27
27
|
from pygeodesy.units import Int_, Lat, Lon, Precision_, Scalar_, Str
|
|
28
28
|
|
|
29
29
|
from math import floor
|
|
30
30
|
|
|
31
31
|
__all__ = _ALL_LAZY.gars
|
|
32
|
-
__version__ = '24.
|
|
32
|
+
__version__ = '24.08.02'
|
|
33
33
|
|
|
34
34
|
_Digits = _0to9_
|
|
35
35
|
_LatLen = 2
|
|
@@ -88,7 +88,7 @@ def _2garstr2(garef):
|
|
|
88
88
|
if n < _MinLen or n > _MaxLen \
|
|
89
89
|
or garstr[:3] == 'INV' \
|
|
90
90
|
or not garstr.isalnum():
|
|
91
|
-
raise ValueError
|
|
91
|
+
raise ValueError()
|
|
92
92
|
return garstr, _2Precision(n - _MinLen)
|
|
93
93
|
|
|
94
94
|
except (AttributeError, TypeError, ValueError) as x:
|
|
@@ -111,45 +111,45 @@ class Garef(Str):
|
|
|
111
111
|
'''Garef class, a named C{str}.
|
|
112
112
|
'''
|
|
113
113
|
# no str.__init__ in Python 3
|
|
114
|
-
def __new__(cls,
|
|
115
|
-
'''New L{Garef} from an other L{Garef} instance or garef
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
@arg
|
|
119
|
-
|
|
120
|
-
@kwarg
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
def __new__(cls, lat_gll, lon=None, precision=1, **name):
|
|
115
|
+
'''New L{Garef} from an other L{Garef} instance or garef C{str}
|
|
116
|
+
or from a lat- and longitude.
|
|
117
|
+
|
|
118
|
+
@arg lat_gll: Latitude (C{degrees90}), a garef (L{Garef},
|
|
119
|
+
C{str}) or a location (C{LatLon}, C{LatLon*Tuple}).
|
|
120
|
+
@kwarg lon: Logitude (C{degrees180)}, required if B{C{lat_gll}}
|
|
121
|
+
is C{degrees90}, ignored otherwise.
|
|
122
|
+
@kwarg precision: The desired garef resolution and length (C{int}
|
|
123
|
+
0..2), see L{encode<pygeodesy.gars.encode>}.
|
|
123
124
|
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
124
125
|
|
|
125
126
|
@return: New L{Garef}.
|
|
126
127
|
|
|
127
|
-
@raise
|
|
128
|
+
@raise GARSError: INValid B{C{lat_gll}}.
|
|
128
129
|
|
|
129
|
-
@raise
|
|
130
|
+
@raise RangeError: Invalid B{C{lat_gll}} or B{C{lon}}.
|
|
130
131
|
|
|
131
|
-
@raise
|
|
132
|
+
@raise TypeError: Invalid B{C{lat_gll}} or B{C{lon}}.
|
|
132
133
|
'''
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
self = Str.__new__(cls, g, name=_name__(name, _or_nameof=cll))
|
|
134
|
+
if lon is None:
|
|
135
|
+
if isinstance(lat_gll, Garef):
|
|
136
|
+
g, ll, p = str(lat_gll), lat_gll.latlon, lat_gll.precision
|
|
137
|
+
elif isstr(lat_gll):
|
|
138
|
+
ll = lat_gll.replace(_COMMA_, _SPACE_).split()
|
|
139
|
+
if len(ll) > 1:
|
|
140
|
+
g, ll, p = _encode3(ll[0], ll[1], precision)
|
|
141
|
+
else:
|
|
142
|
+
g, ll = lat_gll.upper(), None
|
|
143
|
+
_, p = _2garstr2(g) # validate
|
|
144
|
+
else: # assume LatLon
|
|
145
|
+
try:
|
|
146
|
+
g, ll, p = _encode3(lat_gll.lat, lat_gll.lon, precision)
|
|
147
|
+
except AttributeError:
|
|
148
|
+
raise _xStrError(Garef, gll=lat_gll, Error=GARSError)
|
|
149
|
+
else:
|
|
150
|
+
g, ll, p = _encode3(lat_gll, lon, precision)
|
|
151
|
+
|
|
152
|
+
self = Str.__new__(cls, g, name=_name__(name, _or_nameof=lat_gll))
|
|
153
153
|
self._latlon = ll
|
|
154
154
|
self._precision = p
|
|
155
155
|
return self
|
|
@@ -251,7 +251,7 @@ def decode3(garef, center=True, **name):
|
|
|
251
251
|
precision, name=n)
|
|
252
252
|
|
|
253
253
|
|
|
254
|
-
def encode(lat, lon, precision=1):
|
|
254
|
+
def encode(lat, lon, precision=1):
|
|
255
255
|
'''Encode a lat-/longitude as a C{garef} of the given precision.
|
|
256
256
|
|
|
257
257
|
@arg lat: Latitude (C{degrees}).
|
|
@@ -269,6 +269,13 @@ def encode(lat, lon, precision=1): # MCCABE 14
|
|
|
269
269
|
resolution is B{30′} for B{C{precision}} 0, B{15′} for 1
|
|
270
270
|
and B{5′} for 2, respectively.
|
|
271
271
|
'''
|
|
272
|
+
g, _, _ = _encode3(lat, lon, precision)
|
|
273
|
+
return g
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def _encode3(lat, lon, precision): # MCCABE 14
|
|
277
|
+
'''Return 3-tuple C{(garef, (lat, lon), p)}.
|
|
278
|
+
'''
|
|
272
279
|
def _digit(x, y, m):
|
|
273
280
|
return _Digits[m * (m - y - 1) + x + 1],
|
|
274
281
|
|
|
@@ -282,12 +289,12 @@ def encode(lat, lon, precision=1): # MCCABE 14
|
|
|
282
289
|
p = _2Precision(precision)
|
|
283
290
|
|
|
284
291
|
lat, lon = _2fll(lat, lon)
|
|
285
|
-
lat = _off90(lat)
|
|
286
292
|
|
|
287
|
-
ix, x = _2divmod2(lon,
|
|
288
|
-
iy, y = _2divmod2(lat, _LatOrig_M4)
|
|
293
|
+
ix, x = _2divmod2( lon, _LonOrig_M4)
|
|
294
|
+
iy, y = _2divmod2(_off90(lat), _LatOrig_M4)
|
|
289
295
|
|
|
290
|
-
g = _str(_Digits,
|
|
296
|
+
g = _str(_Digits, ix + 1, _LonLen) + \
|
|
297
|
+
_str(_Letters, iy, _LatLen)
|
|
291
298
|
if p > 0:
|
|
292
299
|
ix, x = divmod(x, _M3)
|
|
293
300
|
iy, y = divmod(y, _M3)
|
|
@@ -295,7 +302,7 @@ def encode(lat, lon, precision=1): # MCCABE 14
|
|
|
295
302
|
if p > 1:
|
|
296
303
|
g += _digit(x, y, _M3)
|
|
297
304
|
|
|
298
|
-
return NN.join(g)
|
|
305
|
+
return NN.join(g), (lat, lon), p
|
|
299
306
|
|
|
300
307
|
|
|
301
308
|
def precision(res):
|