pygeodesy 25.4.8__py2.py3-none-any.whl → 25.4.25__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/__init__.py +30 -27
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +9 -9
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +8 -6
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +5 -3
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +31 -17
- pygeodesy/booleans.py +12 -10
- pygeodesy/cartesianBase.py +21 -20
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +10 -7
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +167 -138
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +7 -7
- pygeodesy/fmath.py +10 -9
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +78 -77
- pygeodesy/gars.py +4 -3
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +11 -9
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +5 -5
- pygeodesy/geoids.py +34 -31
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +28 -44
- pygeodesy/interns.py +10 -7
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +68 -62
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +14 -18
- pygeodesy/lazily.py +65 -63
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +8 -7
- pygeodesy/ltpTuples.py +2 -2
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +47 -31
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +11 -10
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +7 -7
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +88 -18
- pygeodesy/vector2d.py +18 -11
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/METADATA +27 -23
- pygeodesy-25.4.25.dist-info/RECORD +118 -0
- pygeodesy-25.4.8.dist-info/RECORD +0 -118
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/WHEEL +0 -0
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.4.25.dist-info}/top_level.txt +0 -0
pygeodesy/trf.py
CHANGED
|
@@ -69,16 +69,18 @@ en/how-to-deal-with-etrs89-datum-and-time-dependent-transformation-parameters-45
|
|
|
69
69
|
@var RefFrames.WGS84g1762: RefFrame(name='WGS84g1762', epoch=2005, datum=Datums.GRS80) .Xforms=(0, 0)
|
|
70
70
|
'''
|
|
71
71
|
|
|
72
|
-
from pygeodesy.basics import map1, neg, isidentifier, isstr, _xinstanceof,
|
|
72
|
+
from pygeodesy.basics import _isin, map1, neg, isidentifier, isstr, _xinstanceof, \
|
|
73
|
+
_xscalar, typename
|
|
73
74
|
from pygeodesy.constants import _float as _F, _0_0s, _0_0, _0_001, _0_5, _1_0
|
|
74
75
|
from pygeodesy.datums import Datums, _earth_datum, _equall, _GDA2020_, _Names7, \
|
|
75
76
|
_negastr, Transform, _WGS84, _EWGS84, _operator
|
|
76
77
|
# from pygeodesy.ellipsoids import _EWGS84 # from .datums
|
|
77
78
|
from pygeodesy.errors import TRFError, _xattr, _xellipsoidall, _xkwds, _xkwds_item2
|
|
79
|
+
# from pygeodesy.internals import typename # from .basics
|
|
78
80
|
from pygeodesy.interns import MISSING, NN, _AT_, _COMMASPACE_, _conversion_, \
|
|
79
|
-
_datum_, _DOT_, _exists_, _invalid_, _MINUS_, \
|
|
80
|
-
_NAD83_, _no_, _PLUS_, _reframe_, _s_, _SPACE_, \
|
|
81
|
-
_STAR_,
|
|
81
|
+
_datum_, _DMAIN_, _DOT_, _exists_, _invalid_, _MINUS_, \
|
|
82
|
+
_NAD83_, _no_, _PLUS_, _reframe_, _s_, _SPACE_, _to_, \
|
|
83
|
+
_STAR_, _vs_, _WGS84_, _x_, _intern as _i
|
|
82
84
|
# from pygeodesy.lazily import _ALL_LAZY # from .units
|
|
83
85
|
from pygeodesy.named import ADict, classname, _lazyNamedEnumItem as _lazy, _name2__, \
|
|
84
86
|
_Named, _NamedEnum, _NamedEnumItem, _NamedTuple, Fmt, unstr
|
|
@@ -91,7 +93,7 @@ from math import ceil as _ceil, fabs
|
|
|
91
93
|
# import operator as _operator # from .datums
|
|
92
94
|
|
|
93
95
|
__all__ = _ALL_LAZY.trf
|
|
94
|
-
__version__ = '
|
|
96
|
+
__version__ = '25.04.14'
|
|
95
97
|
|
|
96
98
|
_EP0CH = Epoch(0, low=0)
|
|
97
99
|
_Es = {_EP0CH: _EP0CH} # L{Epoch}s, deleted below
|
|
@@ -176,9 +178,9 @@ class RefFrame(_NamedEnumItem):
|
|
|
176
178
|
|
|
177
179
|
@raise TypeError: Invalid B{C{datum}}.
|
|
178
180
|
'''
|
|
179
|
-
if datum
|
|
181
|
+
if _isin(datum, None, _GRS80):
|
|
180
182
|
pass
|
|
181
|
-
elif datum
|
|
183
|
+
elif _isin(datum, _WGS84, _EWGS84):
|
|
182
184
|
self._datum = _WGS84
|
|
183
185
|
else:
|
|
184
186
|
_earth_datum(self, datum, raiser=_datum_)
|
|
@@ -1062,8 +1064,8 @@ def _toRefFrame(point, reframe2, reframe=None, epoch=None,
|
|
|
1062
1064
|
e2 = e1 if epoch2 is None else Epoch(epoch2=epoch2)
|
|
1063
1065
|
t0 = _toTransform0(r1.name, e1, reframe2.name, e2)
|
|
1064
1066
|
if t0 is None:
|
|
1065
|
-
t = _SPACE_(RefFrame
|
|
1066
|
-
|
|
1067
|
+
t = _SPACE_(typename(RefFrame), _AT_(r1.name, e1),
|
|
1068
|
+
_to_, _AT_(reframe2.name, e2))
|
|
1067
1069
|
raise TRFError(_no_(_conversion_), txt=t)
|
|
1068
1070
|
|
|
1069
1071
|
name, LatLon_kwds = _name2__(name_LatLon_kwds)
|
|
@@ -1732,7 +1734,7 @@ trfXform(_WGS84g1150_, _ITRF2000_, epoch=_E(2004), xform=_P_0_0s, rates=_P_0_0s
|
|
|
1732
1734
|
|
|
1733
1735
|
del _E, _Es, _i, _P, _P_0_0s, _R, _Rs, _X, _Xs
|
|
1734
1736
|
|
|
1735
|
-
if __name__ ==
|
|
1737
|
+
if __name__ == _DMAIN_:
|
|
1736
1738
|
|
|
1737
1739
|
def _main():
|
|
1738
1740
|
from pygeodesy.basics import _args_kwds_names
|
|
@@ -1740,8 +1742,8 @@ if __name__ == '__main__':
|
|
|
1740
1742
|
from pygeodesy import printf
|
|
1741
1743
|
from time import localtime
|
|
1742
1744
|
|
|
1743
|
-
D = date2epoch
|
|
1744
|
-
E = epoch2date
|
|
1745
|
+
D = typename(date2epoch)
|
|
1746
|
+
E = typename(epoch2date)
|
|
1745
1747
|
y = localtime()[0]
|
|
1746
1748
|
for m in range(1, 13):
|
|
1747
1749
|
for d in (1, 15, _mDays[m] - 1, _mDays[m]):
|
pygeodesy/triaxials.py
CHANGED
|
@@ -17,20 +17,20 @@ see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
|
17
17
|
@var Triaxials.Amalthea: Triaxial(name='Amalthea', a=125000, b=73000, c=64000, e2ab=0.658944, e2bc=0.231375493, e2ac=0.737856, volume=2446253479595252, area=93239507787.490371704, area_p=93212299402.670425415)
|
|
18
18
|
@var Triaxials.Ariel: Triaxial(name='Ariel', a=581100, b=577900, c=577700, e2ab=0.01098327, e2bc=0.000692042, e2ac=0.011667711, volume=812633172614203904, area=4211301462766.580078125, area_p=4211301574065.829589844)
|
|
19
19
|
@var Triaxials.Earth: Triaxial(name='Earth', a=6378173.435, b=6378103.9, c=6356754.399999999, e2ab=0.000021804, e2bc=0.006683418, e2ac=0.006705077, volume=1083208241574987694080, area=510065911057441.0625, area_p=510065915922713.6875)
|
|
20
|
-
@var Triaxials.Enceladus: Triaxial(name='Enceladus', a=256600, b=251400, c=248300, e2ab=0.040119337, e2bc=0.024509841, e2ac=0.06364586, volume=67094551514082248, area=798618496278.596679688, area_p=798619018175.
|
|
20
|
+
@var Triaxials.Enceladus: Triaxial(name='Enceladus', a=256600, b=251400, c=248300, e2ab=0.040119337, e2bc=0.024509841, e2ac=0.06364586, volume=67094551514082248, area=798618496278.596679688, area_p=798619018175.109985352)
|
|
21
21
|
@var Triaxials.Europa: Triaxial(name='Europa', a=1564130, b=1561230, c=1560930, e2ab=0.003704694, e2bc=0.000384275, e2ac=0.004087546, volume=15966575194402123776, area=30663773697323.51953125, area_p=30663773794562.45703125)
|
|
22
22
|
@var Triaxials.Io: Triaxial(name='Io', a=1829400, b=1819300, c=1815700, e2ab=0.011011391, e2bc=0.003953651, e2ac=0.014921506, volume=25313121117889765376, area=41691875849096.7421875, area_p=41691877397441.2109375)
|
|
23
23
|
@var Triaxials.Mars: Triaxial(name='Mars', a=3394600, b=3393300, c=3376300, e2ab=0.000765776, e2bc=0.009994646, e2ac=0.010752768, volume=162907283585817247744, area=144249140795107.4375, area_p=144249144150662.15625)
|
|
24
|
-
@var Triaxials.Mimas: Triaxial(name='Mimas', a=207400, b=196800, c=190600, e2ab=0.09960581, e2bc=0.062015624, e2ac=0.155444317, volume=32587072869017956, area=493855762247.
|
|
25
|
-
@var Triaxials.Miranda: Triaxial(name='Miranda', a=240400, b=234200, c=232900, e2ab=0.050915557, e2bc=0.011070811, e2ac=0.061422691, volume=54926187094835456, area=698880863325.
|
|
26
|
-
@var Triaxials.Moon: Triaxial(name='Moon', a=1735550, b=1735324, c=1734898, e2ab=0.000260419, e2bc=0.000490914, e2ac=0.000751206, volume=21886698675223740416, area=37838824729886.09375, area_p=37838824733332.
|
|
24
|
+
@var Triaxials.Mimas: Triaxial(name='Mimas', a=207400, b=196800, c=190600, e2ab=0.09960581, e2bc=0.062015624, e2ac=0.155444317, volume=32587072869017956, area=493855762247.691833496, area_p=493857714107.9375)
|
|
25
|
+
@var Triaxials.Miranda: Triaxial(name='Miranda', a=240400, b=234200, c=232900, e2ab=0.050915557, e2bc=0.011070811, e2ac=0.061422691, volume=54926187094835456, area=698880863325.757080078, area_p=698881306767.950317383)
|
|
26
|
+
@var Triaxials.Moon: Triaxial(name='Moon', a=1735550, b=1735324, c=1734898, e2ab=0.000260419, e2bc=0.000490914, e2ac=0.000751206, volume=21886698675223740416, area=37838824729886.09375, area_p=37838824733332.21875)
|
|
27
27
|
@var Triaxials.Tethys: Triaxial(name='Tethys', a=535600, b=528200, c=525800, e2ab=0.027441672, e2bc=0.009066821, e2ac=0.036259685, volume=623086233855821440, area=3528073490771.394042969, area_p=3528074261832.738769531)
|
|
28
28
|
@var Triaxials.WGS84_35: Triaxial(name='WGS84_35', a=6378172, b=6378102, c=6356752.314245179, e2ab=0.00002195, e2bc=0.006683478, e2ac=0.006705281, volume=1083207319768789942272, area=510065621722018.125, area_p=510065626587483.3125)
|
|
29
29
|
'''
|
|
30
30
|
# make sure int/int division yields float quotient, see .basics
|
|
31
31
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
32
32
|
|
|
33
|
-
from pygeodesy.basics import isLatLon, isscalar
|
|
33
|
+
from pygeodesy.basics import _isin, isLatLon, isscalar
|
|
34
34
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, INT0, PI2, PI_3, PI4, \
|
|
35
35
|
_EPS2e4, _SQRT2_2, float0_, isfinite, isnear1, _over, \
|
|
36
36
|
_0_0, _0_5, _1_0, _N_1_0, _64_0, _4_0 # PYCHOK used!
|
|
@@ -40,10 +40,10 @@ from pygeodesy.datums import Datum, _spherical_datum, _WGS84, Ellipsoid, _EWGS8
|
|
|
40
40
|
from pygeodesy.errors import _AssertionError, _ValueError
|
|
41
41
|
from pygeodesy.fmath import Fdot, fdot, fmean_, hypot, hypot_, norm2, sqrt0
|
|
42
42
|
from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1f_
|
|
43
|
-
from pygeodesy.interns import NN, _a_, _b_, _beta_, _c_, _distant_,
|
|
44
|
-
_height_, _inside_, _near_, _negative_,
|
|
45
|
-
_NOTEQUAL_, _null_, _opposite_, _outside_,
|
|
46
|
-
_spherical_, _too_, _x_, _y_
|
|
43
|
+
from pygeodesy.interns import NN, _a_, _b_, _beta_, _c_, _distant_, _DMAIN_, \
|
|
44
|
+
_finite_, _height_, _inside_, _near_, _negative_, \
|
|
45
|
+
_not_, _NOTEQUAL_, _null_, _opposite_, _outside_, \
|
|
46
|
+
_SPACE_, _spherical_, _too_, _x_, _y_
|
|
47
47
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .vector3d
|
|
48
48
|
from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, \
|
|
49
49
|
_NamedEnumItem, _Pass
|
|
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
|
|
|
59
59
|
from math import fabs, sqrt
|
|
60
60
|
|
|
61
61
|
__all__ = _ALL_LAZY.triaxials
|
|
62
|
-
__version__ = '
|
|
62
|
+
__version__ = '25.04.14'
|
|
63
63
|
|
|
64
64
|
_not_ordered_ = _not_('ordered')
|
|
65
65
|
_omega_ = 'omega'
|
|
@@ -258,7 +258,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
258
258
|
|
|
259
259
|
@Property_RO
|
|
260
260
|
def _a2_b2(self):
|
|
261
|
-
'''(INTERNAL) Get C{(a/b)**2}.
|
|
261
|
+
'''(INTERNAL) Get C{(a / b)**2}.
|
|
262
262
|
'''
|
|
263
263
|
a, b, _ = self._abc3
|
|
264
264
|
return (a / b)**2 if a != b else _1_0
|
|
@@ -321,7 +321,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
321
321
|
|
|
322
322
|
@Property_RO
|
|
323
323
|
def _c2_b2(self):
|
|
324
|
-
'''(INTERNAL) Get C{(c/b)**2}.
|
|
324
|
+
'''(INTERNAL) Get C{(c / b)**2}.
|
|
325
325
|
'''
|
|
326
326
|
_, b, c = self._abc3
|
|
327
327
|
return (c / b)**2 if b != c else _1_0
|
|
@@ -422,7 +422,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
422
422
|
raise TriaxialError(x=x, y=y, z=z, cause=e)
|
|
423
423
|
if h > 0 and self.sideOf(v, eps=EPS0) < 0:
|
|
424
424
|
h = -h # inside
|
|
425
|
-
n = _name__(name, name__=self.height4) #
|
|
425
|
+
n = _name__(name, name__=self.height4) # typename
|
|
426
426
|
return Vector4Tuple(x, y, z, h, iteration=i, name=n)
|
|
427
427
|
|
|
428
428
|
@Property_RO
|
|
@@ -507,7 +507,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
507
507
|
@return: 2-Tuple C{((a, b, c), ijk)} with C{a} >= C{b} >= C{c}
|
|
508
508
|
and C{ijk} a 3-tuple with the initial indices.
|
|
509
509
|
'''
|
|
510
|
-
i, j, k =
|
|
510
|
+
i, j, k = range(3)
|
|
511
511
|
if a < b:
|
|
512
512
|
a, b, i, j = b, a, j, i
|
|
513
513
|
if a < c:
|
|
@@ -1245,9 +1245,9 @@ def hartzell4(pov, los=False, tri_biax=_WGS84, **name):
|
|
|
1245
1245
|
'''Compute the intersection of a tri-/biaxial ellipsoid and a Line-Of-Sight from
|
|
1246
1246
|
a Point-Of-View outside.
|
|
1247
1247
|
|
|
1248
|
-
@arg pov: Point-Of-View outside the tri-/biaxial (C{Cartesian}, L{Ecef9Tuple}
|
|
1248
|
+
@arg pov: Point-Of-View outside the tri-/biaxial (C{Cartesian}, L{Ecef9Tuple},
|
|
1249
1249
|
C{LatLon} or L{Vector3d}).
|
|
1250
|
-
@kwarg los: Line-Of-Sight, I{direction} to the tri-/biaxial (L{Los}, L{Vector3d})
|
|
1250
|
+
@kwarg los: Line-Of-Sight, I{direction} to the tri-/biaxial (L{Los}, L{Vector3d})
|
|
1251
1251
|
or C{True} for the I{normal, perpendicular, plumb} to the surface of
|
|
1252
1252
|
the tri-/biaxial or C{False} or C{None} to point to its center.
|
|
1253
1253
|
@kwarg tri_biax: A triaxial (L{Triaxial}, L{Triaxial_}, L{JacobiConformal} or
|
|
@@ -1275,13 +1275,13 @@ def hartzell4(pov, los=False, tri_biax=_WGS84, **name):
|
|
|
1275
1275
|
T = tri_biax
|
|
1276
1276
|
else:
|
|
1277
1277
|
D = tri_biax if isinstance(tri_biax, Datum) else \
|
|
1278
|
-
_spherical_datum(tri_biax, name__=hartzell4) #
|
|
1278
|
+
_spherical_datum(tri_biax, name__=hartzell4) # typename
|
|
1279
1279
|
T = D.ellipsoid._triaxial
|
|
1280
1280
|
try:
|
|
1281
1281
|
v, h, i = _hartzell3(pov, los, T)
|
|
1282
1282
|
except Exception as x:
|
|
1283
1283
|
raise TriaxialError(pov=pov, los=los, tri_biax=tri_biax, cause=x)
|
|
1284
|
-
n = _name__(name, name__=hartzell4) #
|
|
1284
|
+
n = _name__(name, name__=hartzell4) # typename
|
|
1285
1285
|
return Vector4Tuple(v.x, v.y, v.z, h, iteration=i, name=n)
|
|
1286
1286
|
|
|
1287
1287
|
|
|
@@ -1478,19 +1478,18 @@ def _rootNd(r, s, u, v, w, g, eps=EPS0):
|
|
|
1478
1478
|
'''
|
|
1479
1479
|
u *= r
|
|
1480
1480
|
v *= s # 0 for 2-D root
|
|
1481
|
-
t0 = w
|
|
1482
|
-
t1 = _0_0 if g < 0 else (hypot_(u, w, v)
|
|
1481
|
+
t0 = w - _1_0
|
|
1482
|
+
t1 = _0_0 if g < 0 else (hypot_(u, w, v) - _1_0)
|
|
1483
1483
|
# assert t0 <= t1
|
|
1484
|
-
|
|
1485
|
-
for i in range(1, _TRIPS): # 47..65
|
|
1484
|
+
for i in range(1, _TRIPS): # 48..58
|
|
1486
1485
|
t = (t1 + t0) * _0_5
|
|
1487
1486
|
e = t1 - t0
|
|
1488
|
-
if
|
|
1487
|
+
if eps > e > -eps or _isin(t, t0, t1):
|
|
1489
1488
|
break
|
|
1490
1489
|
g = fsumf_(_N_1_0, # ~= _hypot2_1
|
|
1491
1490
|
_over02(u, t + r),
|
|
1492
|
-
_over02(w, t
|
|
1493
|
-
_over02(v, t + s) if v else _0_0)
|
|
1491
|
+
_over02(w, t + _1_0), (
|
|
1492
|
+
_over02(v, t + s) if v else _0_0))
|
|
1494
1493
|
if g > 0:
|
|
1495
1494
|
t0 = t
|
|
1496
1495
|
elif g < 0:
|
|
@@ -1527,7 +1526,7 @@ def _validate(a, b, c, d, T, x, y, z, val):
|
|
|
1527
1526
|
dot=e, eps=val)
|
|
1528
1527
|
|
|
1529
1528
|
|
|
1530
|
-
if __name__ ==
|
|
1529
|
+
if __name__ == _DMAIN_:
|
|
1531
1530
|
|
|
1532
1531
|
from pygeodesy import printf
|
|
1533
1532
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
@@ -1540,6 +1539,10 @@ if __name__ == '__main__':
|
|
|
1540
1539
|
t = [NN] + Triaxials.toRepr(all=True, asorted=True).split(_NL_)
|
|
1541
1540
|
printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
|
|
1542
1541
|
|
|
1542
|
+
# % python3 -m pygeodesy.triaxials
|
|
1543
|
+
#
|
|
1544
|
+
# Bektas: height4(x=3909251.554667, y=3909165.750567, z=3170432.501602, h=999.999996)
|
|
1545
|
+
|
|
1543
1546
|
# **) MIT License
|
|
1544
1547
|
#
|
|
1545
1548
|
# Copyright (C) 2022-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
pygeodesy/units.py
CHANGED
|
@@ -6,11 +6,12 @@ basic C{float}, C{int} respectively C{str} to named units as L{Degrees},
|
|
|
6
6
|
L{Feet}, L{Meter}, L{Radians}, etc.
|
|
7
7
|
'''
|
|
8
8
|
|
|
9
|
-
from pygeodesy.basics import isscalar, issubclassof, signOf
|
|
9
|
+
from pygeodesy.basics import isscalar, issubclassof, signOf, typename
|
|
10
10
|
from pygeodesy.constants import EPS, EPS1, PI, PI2, PI_2, _umod_360, _0_0, \
|
|
11
11
|
_0_001, _0_5, INT0 # PYCHOK for .mgrs, .namedTuples
|
|
12
12
|
from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, _toDMS
|
|
13
13
|
from pygeodesy.errors import _AssertionError, TRFError, UnitError, _xattr, _xcallable
|
|
14
|
+
# from pygeodesy.internals import typename # from .basics
|
|
14
15
|
from pygeodesy.interns import NN, _azimuth_, _band_, _bearing_, _COMMASPACE_, \
|
|
15
16
|
_degrees_, _degrees2_, _distance_, _E_, _easting_, \
|
|
16
17
|
_epoch_, _EW_, _feet_, _height_, _lam_, _lat_, _LatLon_, \
|
|
@@ -27,7 +28,7 @@ from pygeodesy.unitsBase import Float, Int, _NamedUnit, Radius, Str, Fmt, fstr
|
|
|
27
28
|
from math import degrees, isnan, radians
|
|
28
29
|
|
|
29
30
|
__all__ = _ALL_LAZY.units
|
|
30
|
-
__version__ = '
|
|
31
|
+
__version__ = '25.04.14'
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
class Float_(Float):
|
|
@@ -860,8 +861,8 @@ def _std_repr(*Classes):
|
|
|
860
861
|
'''
|
|
861
862
|
from pygeodesy.internals import _getenv
|
|
862
863
|
for C in Classes:
|
|
863
|
-
if hasattr(C, _std_repr
|
|
864
|
-
env = 'PYGEODESY_%s_STD_REPR' % (C.
|
|
864
|
+
if hasattr(C, typename(_std_repr)): # PYCHOK del _std_repr
|
|
865
|
+
env = 'PYGEODESY_%s_STD_REPR' % (typename(C).upper(),)
|
|
865
866
|
if _getenv(env, _std_).lower() != _std_:
|
|
866
867
|
C._std_repr = False
|
|
867
868
|
|
pygeodesy/unitsBase.py
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
u'''Basic C{Float}, C{Int} and C{Str}ing units classes.
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
|
-
from pygeodesy.basics import isstr, issubclassof, _xsubclassof
|
|
7
|
+
from pygeodesy.basics import _isin, isstr, issubclassof, _xsubclassof, typename
|
|
8
8
|
from pygeodesy.errors import _IsnotError, _UnexpectedError, UnitError, _XError
|
|
9
|
+
# from pygeodesy.internals import typename # from .basics
|
|
9
10
|
from pygeodesy.interns import NN, _degrees_, _degrees2_, _invalid_, _meter_, \
|
|
10
11
|
_radians_, _radians2_, _radius_, _UNDER_, _units_, \
|
|
11
12
|
_std_ # PYCHOK used!
|
|
@@ -15,7 +16,7 @@ from pygeodesy.named import modulename, _Named, property_doc_
|
|
|
15
16
|
from pygeodesy.streprs import Fmt, fstr
|
|
16
17
|
|
|
17
18
|
__all__ = _ALL_LAZY.unitsBase
|
|
18
|
-
__version__ = '
|
|
19
|
+
__version__ = '25.04.14'
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class _NamedUnit(_Named):
|
|
@@ -49,7 +50,7 @@ class _NamedUnit(_Named):
|
|
|
49
50
|
elif name:
|
|
50
51
|
pass
|
|
51
52
|
elif name__ is not None:
|
|
52
|
-
name = name__
|
|
53
|
+
name = typename(name__)
|
|
53
54
|
return name, arg
|
|
54
55
|
|
|
55
56
|
@staticmethod # PYCHOK unused suffix
|
|
@@ -84,7 +85,7 @@ class _NamedUnit(_Named):
|
|
|
84
85
|
def std_repr(self, std):
|
|
85
86
|
'''Set the representation (C{True} or C{"std"} for standard).
|
|
86
87
|
'''
|
|
87
|
-
self._std_repr = std
|
|
88
|
+
self._std_repr = _isin(std, True, _std_)
|
|
88
89
|
|
|
89
90
|
def _toRepr(self, value):
|
|
90
91
|
'''(INTERNAL) Representation "<name> (<value>)" or "<classname>(<value>)".
|
pygeodesy/ups.py
CHANGED
|
@@ -28,7 +28,7 @@ from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
|
28
28
|
from pygeodesy.dms import degDMS, _neg, parseDMS2
|
|
29
29
|
from pygeodesy.errors import RangeError, _ValueError, _xkwds_pop2
|
|
30
30
|
from pygeodesy.fmath import hypot, hypot1, sqrt0
|
|
31
|
-
from pygeodesy.internals import
|
|
31
|
+
from pygeodesy.internals import _envPYGEODESY, _under
|
|
32
32
|
from pygeodesy.interns import NN, _COMMASPACE_, _inside_, _N_, \
|
|
33
33
|
_pole_, _range_, _S_, _scale0_, \
|
|
34
34
|
_SPACE_, _std_, _to_, _UTM_
|
|
@@ -49,9 +49,9 @@ from pygeodesy.utmupsBase import Fmt, _LLEB, _hemi, _parseUTMUPS5, _to4lldn, \
|
|
|
49
49
|
from math import fabs, radians, tan # as _tan
|
|
50
50
|
|
|
51
51
|
__all__ = _ALL_LAZY.ups
|
|
52
|
-
__version__ = '
|
|
52
|
+
__version__ = '25.04.14'
|
|
53
53
|
|
|
54
|
-
_BZ_UPS =
|
|
54
|
+
_BZ_UPS = _envPYGEODESY('UPS_POLES', _std_) == _std_
|
|
55
55
|
_Falsing = Meter(2000e3) # false easting and northing (C{meter})
|
|
56
56
|
_K0_UPS = Float(_K0_UPS= 0.994) # scale factor at central meridian
|
|
57
57
|
_K1_UPS = Float(_K1_UPS=_1_0) # rescale point scale factor
|
pygeodesy/utily.py
CHANGED
|
@@ -18,7 +18,7 @@ from pygeodesy.constants import EPS, EPS0, INF, NAN, PI, PI2, PI_2, R_M, \
|
|
|
18
18
|
_copysign_0_0, _float, _isfinite, isnan, isnear0, \
|
|
19
19
|
_over, _umod_360, _umod_PI2
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xkwds, _ALL_LAZY, _MODS
|
|
21
|
-
from pygeodesy.internals import _passargs
|
|
21
|
+
from pygeodesy.internals import _passargs, typename
|
|
22
22
|
from pygeodesy.interns import _edge_, _radians_, _semi_circular_, _SPACE_
|
|
23
23
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .errors
|
|
24
24
|
from pygeodesy.units import Degrees, Degrees_, Feet, Float, Lam, Lamd, \
|
|
@@ -28,7 +28,7 @@ from math import acos, asin, atan2 as _atan2, cos, degrees, fabs, radians, \
|
|
|
28
28
|
sin, tan as _tan # pow
|
|
29
29
|
|
|
30
30
|
__all__ = _ALL_LAZY.utily
|
|
31
|
-
__version__ = '25.
|
|
31
|
+
__version__ = '25.04.14'
|
|
32
32
|
|
|
33
33
|
_G_DEG = _float( 400.0 / _360_0) # grades per degree
|
|
34
34
|
_G_RAD = _float( 400.0 / PI2) # grades per radian
|
|
@@ -1109,7 +1109,7 @@ def unrollPI(rad1, rad2, wrap=True):
|
|
|
1109
1109
|
def _valueError(where, x, raiser=True, **kwds):
|
|
1110
1110
|
'''(INTERNAL) Return a C{_ValueError} or C{None}.
|
|
1111
1111
|
'''
|
|
1112
|
-
t = _MODS.streprs.Fmt.PAREN(where
|
|
1112
|
+
t = _MODS.streprs.Fmt.PAREN(typename(where), x)
|
|
1113
1113
|
return _ValueError(t, **kwds) if raiser else None
|
|
1114
1114
|
|
|
1115
1115
|
|
|
@@ -1193,7 +1193,7 @@ class _Wrap(object):
|
|
|
1193
1193
|
lat, lon = ll.latlon
|
|
1194
1194
|
if fabs(lon) > _180_0 or fabs(lat) > _90_0:
|
|
1195
1195
|
_n = self.latlon
|
|
1196
|
-
ll = ll.copy(name=_n
|
|
1196
|
+
ll = ll.copy(name=typename(_n))
|
|
1197
1197
|
ll.latlon = _n(lat, lon)
|
|
1198
1198
|
return ll
|
|
1199
1199
|
|
pygeodesy/utmups.py
CHANGED
|
@@ -14,14 +14,14 @@ A pure Python implementation, partially transcoded from C++ class U{UTMUPS
|
|
|
14
14
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1UTMUPS.html>}
|
|
15
15
|
by I{Charles Karney}.
|
|
16
16
|
'''
|
|
17
|
-
|
|
17
|
+
from pygeodesy.basics import _isin, map1
|
|
18
18
|
# from pygeodesy.datums import _WGS84 # from .utmupsBase
|
|
19
19
|
from pygeodesy.errors import _IsnotError, RangeError, _ValueError, _xkwds_pop2
|
|
20
20
|
from pygeodesy.interns import NN, _easting_, _MGRS_, _northing_, _NS_, \
|
|
21
21
|
_outside_, _range_, _SPACE_, _UPS_, _UTM_
|
|
22
22
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
23
23
|
from pygeodesy.named import modulename
|
|
24
|
-
from pygeodesy.namedTuples import UtmUps5Tuple, UtmUps8Tuple
|
|
24
|
+
from pygeodesy.namedTuples import UtmUps5Tuple, UtmUps8Tuple
|
|
25
25
|
# from pygeodesy.streprs import Fmt # from .utmupsBase
|
|
26
26
|
from pygeodesy.units import Northing, _100km
|
|
27
27
|
from pygeodesy.ups import parseUPS5, toUps8, Ups, UPSError, upsZoneBand5
|
|
@@ -31,7 +31,7 @@ from pygeodesy.utmupsBase import Fmt, _to4lldn, _to3zBhp, _UPS_ZONE, \
|
|
|
31
31
|
_UTMUPS_ZONE_MAX, _WGS84
|
|
32
32
|
|
|
33
33
|
__all__ = _ALL_LAZY.utmups
|
|
34
|
-
__version__ = '
|
|
34
|
+
__version__ = '25.04.14'
|
|
35
35
|
|
|
36
36
|
_MGRS_TILE = _100km # in .mgrs.Mgrs.tile
|
|
37
37
|
|
|
@@ -179,7 +179,7 @@ def UtmUps(zone, hemipole, easting, northing, band=NN, datum=_WGS84, falsed=True
|
|
|
179
179
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1UTMUPS.html>}.
|
|
180
180
|
'''
|
|
181
181
|
z, B, hp = _to3zBhp(zone, band, hemipole=hemipole)
|
|
182
|
-
U = Ups if z
|
|
182
|
+
U = Ups if _isin(z, _UPS_ZONE, _UPS_ZONE_STR) else Utm
|
|
183
183
|
return U(z, hp, easting, northing, band=B, datum=datum, falsed=falsed, **name)
|
|
184
184
|
|
|
185
185
|
|
pygeodesy/utmupsBase.py
CHANGED
|
@@ -4,39 +4,44 @@
|
|
|
4
4
|
u'''(INTERNAL) Private class C{UtmUpsBase}, functions and constants
|
|
5
5
|
for modules L{epsg}, L{etm}, L{mgrs}, L{ups} and L{utm}.
|
|
6
6
|
'''
|
|
7
|
+
# make sure int/int division yields float quotient, see .basics
|
|
8
|
+
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
7
9
|
|
|
8
|
-
from pygeodesy.basics import isint, isscalar, isstr, neg_, \
|
|
9
|
-
|
|
10
|
+
from pygeodesy.basics import _isin, isint, isscalar, isstr, neg_, \
|
|
11
|
+
_xinstanceof, _xsubclassof
|
|
10
12
|
from pygeodesy.constants import _float, _0_0, _0_5, _N_90_0, _180_0
|
|
11
13
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
12
14
|
from pygeodesy.dms import degDMS, parseDMS2
|
|
13
15
|
from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
|
|
14
16
|
from pygeodesy.errors import _or, ParseError, _parseX, _ValueError, \
|
|
15
17
|
_xattrs, _xkwds, _xkwds_not
|
|
18
|
+
# from pygeodesy.fsums import Fsum # _MODS
|
|
16
19
|
# from pygeodesy.internals import _name__, _under # from .named
|
|
17
|
-
from pygeodesy.interns import NN, _A_, _B_, _COMMA_, _Error_, \
|
|
18
|
-
|
|
19
|
-
_S_,
|
|
20
|
+
from pygeodesy.interns import NN, _A_, _B_, _COMMA_, _Error_, _gamma_, \
|
|
21
|
+
_n_a_, _not_, _N_, _NS_, _PLUS_, _scale_, \
|
|
22
|
+
_S_, _SPACE_, _Y_, _Z_
|
|
20
23
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
21
24
|
from pygeodesy.named import _name__, _NamedBase, _under
|
|
22
25
|
from pygeodesy.namedTuples import EasNor2Tuple, LatLonDatum5Tuple
|
|
23
26
|
from pygeodesy.props import deprecated_method, property_doc_, _update_all, \
|
|
24
27
|
deprecated_property_RO, Property_RO, property_RO
|
|
25
28
|
from pygeodesy.streprs import Fmt, fstr, _fstrENH2, _xzipairs
|
|
26
|
-
from pygeodesy.units import Band, Easting, Northing, Scalar, Zone
|
|
27
|
-
from pygeodesy.utily import _Wrap, wrap360
|
|
29
|
+
from pygeodesy.units import Band, Easting, Lat, Northing, Phi, Scalar, Zone
|
|
30
|
+
from pygeodesy.utily import atan1, _Wrap, wrap360
|
|
31
|
+
|
|
32
|
+
from math import cos, degrees, fabs, sin, tan
|
|
28
33
|
|
|
29
34
|
__all__ = _ALL_LAZY.utmupsBase
|
|
30
|
-
__version__ = '
|
|
35
|
+
__version__ = '25.04.25'
|
|
31
36
|
|
|
32
37
|
_UPS_BANDS = _A_, _B_, _Y_, _Z_ # UPS polar bands SE, SW, NE, NW
|
|
33
38
|
# _UTM_BANDS = _MODS.utm._Bands
|
|
34
39
|
|
|
35
|
-
_UTM_LAT_MAX
|
|
36
|
-
_UTM_LAT_MIN
|
|
40
|
+
_UTM_LAT_MAX = _float( 84) # PYCHOK for export (C{degrees})
|
|
41
|
+
_UTM_LAT_MIN = _float(-80) # PYCHOK for export (C{degrees})
|
|
37
42
|
|
|
38
|
-
_UPS_LAT_MAX
|
|
39
|
-
_UPS_LAT_MIN
|
|
43
|
+
_UPS_LAT_MAX = _UTM_LAT_MAX - _0_5 # PYCHOK includes 30' UTM overlap
|
|
44
|
+
_UPS_LAT_MIN = _UTM_LAT_MIN + _0_5 # PYCHOK includes 30' UTM overlap
|
|
40
45
|
|
|
41
46
|
_UPS_LATS = {_A_: _N_90_0, _Y_: _UTM_LAT_MAX, # UPS band bottom latitudes,
|
|
42
47
|
_B_: _N_90_0, _Z_: _UTM_LAT_MAX} # PYCHOK see .Mgrs.bandLatitude
|
|
@@ -91,7 +96,7 @@ class UtmUpsBase(_NamedBase):
|
|
|
91
96
|
if band:
|
|
92
97
|
self._band1(band)
|
|
93
98
|
|
|
94
|
-
if
|
|
99
|
+
if not _isin(datum, None, self._datum):
|
|
95
100
|
self._datum = _ellipsoidal_datum(datum) # raiser=_datum_, name=band
|
|
96
101
|
|
|
97
102
|
if not falsed:
|
|
@@ -189,6 +194,45 @@ class UtmUpsBase(_NamedBase):
|
|
|
189
194
|
'''I{Must be overloaded}.'''
|
|
190
195
|
self._notOverloaded(self)
|
|
191
196
|
|
|
197
|
+
def _footpoint(self, y, lat0, makris):
|
|
198
|
+
'''(INTERNAL) Compute to foot-point latitude in C{radians}.
|
|
199
|
+
'''
|
|
200
|
+
if y is None:
|
|
201
|
+
_, y = self.eastingnorthing2(falsed=False)
|
|
202
|
+
S = _MODS.fsums.Fsum
|
|
203
|
+
E = self.datum.ellipsoid
|
|
204
|
+
P = S(E.Llat(lat0), y)
|
|
205
|
+
if E.isSpherical:
|
|
206
|
+
p = P.fover(E.a)
|
|
207
|
+
elif makris:
|
|
208
|
+
r = P.fover(E.b)
|
|
209
|
+
p = fabs(r)
|
|
210
|
+
if p:
|
|
211
|
+
e2 = E.e22 # E.e22abs?
|
|
212
|
+
e4 = E.e4
|
|
213
|
+
|
|
214
|
+
e1 = S(e2 / 4, -11 / 64 * e4, -1).as_iscalar
|
|
215
|
+
e2 = S(e2 / 8, -13 / 128 * e4) .as_iscalar
|
|
216
|
+
e4 *= cos(p)**2 / 8
|
|
217
|
+
|
|
218
|
+
s = sin(p * 2)
|
|
219
|
+
p = -p
|
|
220
|
+
U = S(e1 * p, e2 * s, e4 * p, (5 / 8 * e4) * s**2)
|
|
221
|
+
p = atan1(E.a * tan(float(U)) / E.b)
|
|
222
|
+
if r < 0: # copysign(p, y)
|
|
223
|
+
p = -p
|
|
224
|
+
else: # PyGeodetics
|
|
225
|
+
f = E.f
|
|
226
|
+
f2 = f**2
|
|
227
|
+
f3 = f**3
|
|
228
|
+
B0 = S(1, -f / 2, f2 / 16, f3 / 32) * E.a
|
|
229
|
+
r = P.fover(B0)
|
|
230
|
+
P = S(r, S(3 / 4 * f, 3 / 8 * f2, 21 / 256 * f3) * sin(r * 2),
|
|
231
|
+
S( 21 / 64 * f2, 21 / 64 * f3) * sin(r * 4),
|
|
232
|
+
151 / 768 * f3 * sin(r * 6))
|
|
233
|
+
p = float(P)
|
|
234
|
+
return p
|
|
235
|
+
|
|
192
236
|
@Property_RO
|
|
193
237
|
def gamma(self):
|
|
194
238
|
'''Get the meridian convergence (C{degrees}) or C{None}
|
|
@@ -204,6 +248,23 @@ class UtmUpsBase(_NamedBase):
|
|
|
204
248
|
self._toLLEB()
|
|
205
249
|
return self._hemisphere
|
|
206
250
|
|
|
251
|
+
def latFootPoint(self, northing=None, lat0=0, makris=False):
|
|
252
|
+
'''Compute the foot-point latitude in C{degrees}.
|
|
253
|
+
|
|
254
|
+
@arg northing: Northing (C{meter}, same units this datum's ellipsoid's axes),
|
|
255
|
+
overriding this I{unfalsed} northing.
|
|
256
|
+
@kwarg lat0: Geodetic latitude of the meridian's origin (C{degrees}).
|
|
257
|
+
@kwarg makris: If C{True}, use C{Makris}' formula, otherwise C{PyGeodetics}'.
|
|
258
|
+
|
|
259
|
+
@return: Foot-point latitude (C{degrees}).
|
|
260
|
+
|
|
261
|
+
@see: U{PyGeodetics<https://GitHub.com/paarnes/pygeodetics>}, U{FootpointLatitude
|
|
262
|
+
<https://GitHub.com/APRIL-ZJU/clins/blob/master/include/utils/gps_convert_utils.h#L143>},
|
|
263
|
+
U{Makris<https://www.TandFonline.com/doi/abs/10.1179/sre.1982.26.205.345>} and
|
|
264
|
+
U{Geomatics' Mercator, page 60<https://Geomatics.CC/legacy-files/mercator.pdf>}.
|
|
265
|
+
'''
|
|
266
|
+
return Lat(FootPoint=degrees(self._footpoint(northing, lat0, makris)))
|
|
267
|
+
|
|
207
268
|
def _latlon5(self, LatLon, **LatLon_kwds):
|
|
208
269
|
'''(INTERNAL) Get cached C{._toLLEB} as B{C{LatLon}} instance.
|
|
209
270
|
'''
|
|
@@ -255,6 +316,15 @@ class UtmUpsBase(_NamedBase):
|
|
|
255
316
|
'''
|
|
256
317
|
return self._northing
|
|
257
318
|
|
|
319
|
+
def phiFootPoint(self, northing=None, lat0=0, makris=False):
|
|
320
|
+
'''Compute the foot-point latitude in C{radians}.
|
|
321
|
+
|
|
322
|
+
@return: Foot-point latitude (C{radians}).
|
|
323
|
+
|
|
324
|
+
@see: Method L{latFootPoint<UtmUpsBase.latFootPoint>} for further details.
|
|
325
|
+
'''
|
|
326
|
+
return Phi(FootPoint=self._footpoint(northing, lat0, makris))
|
|
327
|
+
|
|
258
328
|
@Property_RO
|
|
259
329
|
def scale(self):
|
|
260
330
|
'''Get the grid scale (C{float}) or C{None}.
|
|
@@ -302,9 +372,9 @@ class UtmUpsBase(_NamedBase):
|
|
|
302
372
|
@note: If not specified, the I{latitudinal} C{band} is computed from
|
|
303
373
|
the (geodetic) latitude and the C{datum}.
|
|
304
374
|
'''
|
|
305
|
-
return self.
|
|
306
|
-
|
|
307
|
-
|
|
375
|
+
return self._mgrs_lowerleft if center is True else (
|
|
376
|
+
_toMgrs(_lowerleft(self, center)) if center else
|
|
377
|
+
self._mgrs) # PYCHOK indent
|
|
308
378
|
|
|
309
379
|
def _toRepr(self, fmt, B, cs, prec, sep): # PYCHOK expected
|
|
310
380
|
'''(INTERNAL) Return a representation for this ETM/UTM/UPS coordinate.
|
|
@@ -349,8 +419,8 @@ def _lowerleft(utmups, center): # in .ellipsoidalBase._lowerleft
|
|
|
349
419
|
t = c * 2
|
|
350
420
|
e = int(utmups.easting % t)
|
|
351
421
|
n = int(utmups.northing % t)
|
|
352
|
-
if (e == c and n
|
|
353
|
-
(n == c and e
|
|
422
|
+
if (e == c and _isin(n, c, c - 1)) or \
|
|
423
|
+
(n == c and _isin(e, c, c - 1)):
|
|
354
424
|
break
|
|
355
425
|
else:
|
|
356
426
|
return utmups # unchanged
|