pygeodesy 24.5.24__py2.py3-none-any.whl → 24.6.1__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.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/RECORD +57 -57
- pygeodesy/__init__.py +4 -4
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +4 -4
- pygeodesy/basics.py +39 -5
- pygeodesy/booleans.py +3 -3
- pygeodesy/constants.py +3 -3
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/ecef.py +22 -21
- pygeodesy/ellipsoidalBase.py +15 -16
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoids.py +6 -5
- pygeodesy/errors.py +19 -9
- pygeodesy/etm.py +16 -21
- pygeodesy/fmath.py +9 -20
- pygeodesy/formy.py +60 -74
- pygeodesy/frechet.py +11 -11
- pygeodesy/fsums.py +59 -25
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +3 -5
- pygeodesy/geodsolve.py +2 -2
- pygeodesy/geohash.py +14 -14
- pygeodesy/hausdorff.py +12 -12
- pygeodesy/heights.py +5 -5
- pygeodesy/internals.py +3 -3
- pygeodesy/karney.py +8 -7
- pygeodesy/lazily.py +2 -2
- pygeodesy/ltp.py +62 -44
- pygeodesy/ltpTuples.py +202 -147
- pygeodesy/mgrs.py +24 -24
- pygeodesy/named.py +68 -70
- pygeodesy/nvectorBase.py +2 -2
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +10 -10
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +13 -10
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +14 -14
- pygeodesy/sphericalBase.py +17 -21
- pygeodesy/sphericalTrigonometry.py +17 -17
- pygeodesy/trf.py +9 -7
- pygeodesy/triaxials.py +2 -2
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +3 -3
- pygeodesy/utm.py +152 -156
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +102 -106
- pygeodesy/webmercator.py +43 -51
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.24.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/sphericalBase.py
CHANGED
|
@@ -21,18 +21,18 @@ from pygeodesy.datums import Datums, _earth_ellipsoid, _spherical_datum
|
|
|
21
21
|
from pygeodesy.errors import IntersectionError, _ValueError, \
|
|
22
22
|
_xattr, _xError
|
|
23
23
|
from pygeodesy.fmath import favg, fdot, hypot, sqrt_a
|
|
24
|
-
from pygeodesy.interns import
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
from pygeodesy.interns import _COMMA_, _concentric_, _datum_, _distant_, \
|
|
25
|
+
_exceed_PI_radians_, _name_, _near_, \
|
|
26
|
+
_radius_, _too_
|
|
27
27
|
from pygeodesy.latlonBase import LatLonBase, _trilaterate5 # PYCHOK passed
|
|
28
28
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
29
29
|
# from pygeodesy.namedTuples import Bearing2Tuple # from .cartesianBase
|
|
30
30
|
from pygeodesy.nvectorBase import NvectorBase, Fmt, _xattrs
|
|
31
|
-
from pygeodesy.props import deprecated_method, property_doc_, \
|
|
32
|
-
|
|
31
|
+
from pygeodesy.props import deprecated_method, property_doc_, property_RO, \
|
|
32
|
+
_update_all
|
|
33
33
|
# from pygeodesy.streprs import Fmt, _xattrs # from .nvectorBase
|
|
34
|
-
from pygeodesy.units import
|
|
35
|
-
|
|
34
|
+
from pygeodesy.units import Bearing, Bearing_, _isRadius, Radians_, Radius, \
|
|
35
|
+
Radius_, Scalar_, _100km
|
|
36
36
|
from pygeodesy.utily import acos1, asin1, atan2b, atan2d, degrees90, \
|
|
37
37
|
degrees180, sincos2, sincos2d, _unrollon, \
|
|
38
38
|
tanPI_2_2, wrapPI
|
|
@@ -40,7 +40,7 @@ from pygeodesy.utily import acos1, asin1, atan2b, atan2d, degrees90, \
|
|
|
40
40
|
from math import cos, fabs, log, sin, sqrt
|
|
41
41
|
|
|
42
42
|
__all__ = _ALL_LAZY.sphericalBase
|
|
43
|
-
__version__ = '
|
|
43
|
+
__version__ = '24.05.31'
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class CartesianSphericalBase(CartesianBase):
|
|
@@ -117,7 +117,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
117
117
|
_datum = Datums.Sphere # spherical L{Datum}
|
|
118
118
|
_napieradius = _100km
|
|
119
119
|
|
|
120
|
-
def __init__(self, latlonh, lon=None, height=0, datum=None, wrap=False, name
|
|
120
|
+
def __init__(self, latlonh, lon=None, height=0, datum=None, wrap=False, **name):
|
|
121
121
|
'''Create a spherical C{LatLon} point frome the given lat-, longitude and
|
|
122
122
|
height on the given datum.
|
|
123
123
|
|
|
@@ -132,12 +132,12 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
132
132
|
conventionally).
|
|
133
133
|
@kwarg wrap: If C{True}, wrap or I{normalize} B{C{lat}} and B{C{lon}}
|
|
134
134
|
(C{bool}).
|
|
135
|
-
@kwarg name: Optional name (C{str}).
|
|
135
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
136
136
|
|
|
137
137
|
@raise TypeError: If B{C{latlonh}} is not a C{LatLon} or B{C{datum}} not
|
|
138
138
|
spherical.
|
|
139
139
|
'''
|
|
140
|
-
LatLonBase.__init__(self, latlonh, lon=lon, height=height, wrap=wrap, name
|
|
140
|
+
LatLonBase.__init__(self, latlonh, lon=lon, height=height, wrap=wrap, **name)
|
|
141
141
|
if datum not in (None, self.datum):
|
|
142
142
|
self.datum = datum
|
|
143
143
|
|
|
@@ -302,26 +302,22 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
302
302
|
# raise _xError(x, this=self, point=point, other=other, **radius_exact_height_wrap)
|
|
303
303
|
# return p.midpointTo(q)
|
|
304
304
|
|
|
305
|
-
def parse(self, strllh, height=0, sep=_COMMA_, name
|
|
305
|
+
def parse(self, strllh, height=0, sep=_COMMA_, **name):
|
|
306
306
|
'''Parse a string representing a similar, spherical C{LatLon}
|
|
307
307
|
point, consisting of C{"lat, lon[, height]"}.
|
|
308
308
|
|
|
309
|
-
@arg strllh: Lat, lon and optional height (C{str}),
|
|
310
|
-
|
|
309
|
+
@arg strllh: Lat, lon and optional height (C{str}), see function
|
|
310
|
+
L{pygeodesy.parse3llh}.
|
|
311
311
|
@kwarg height: Optional, default height (C{meter}).
|
|
312
312
|
@kwarg sep: Optional separator (C{str}).
|
|
313
|
-
@kwarg name: Optional
|
|
314
|
-
overriding this name.
|
|
313
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
|
|
315
314
|
|
|
316
315
|
@return: The similar point (spherical C{LatLon}).
|
|
317
316
|
|
|
318
317
|
@raise ParseError: Invalid B{C{strllh}}.
|
|
319
318
|
'''
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if name:
|
|
323
|
-
r.rename(name)
|
|
324
|
-
return r
|
|
319
|
+
llh = _MODS.dms.parse3llh(strllh, height=height, sep=sep)
|
|
320
|
+
return self.classof(*llh, **name)
|
|
325
321
|
|
|
326
322
|
@property_RO
|
|
327
323
|
def _radius(self):
|
|
@@ -54,7 +54,7 @@ from pygeodesy.vector3d import sumOf, Vector3d
|
|
|
54
54
|
from math import asin, atan2, cos, degrees, fabs, radians, sin
|
|
55
55
|
|
|
56
56
|
__all__ = _ALL_LAZY.sphericalTrigonometry
|
|
57
|
-
__version__ = '24.
|
|
57
|
+
__version__ = '24.05.25'
|
|
58
58
|
|
|
59
59
|
_PI_EPS4 = PI - EPS4
|
|
60
60
|
if _PI_EPS4 >= PI:
|
|
@@ -538,7 +538,7 @@ class LatLon(LatLonSphericalBase):
|
|
|
538
538
|
def nearestOn(self, point1, point2, radius=R_M, **wrap_adjust_limit):
|
|
539
539
|
'''Locate the point between two points closest to this point.
|
|
540
540
|
|
|
541
|
-
Distances are approximated by function L{pygeodesy.
|
|
541
|
+
Distances are approximated by function L{pygeodesy.equirectangular4},
|
|
542
542
|
subject to the supplied B{C{options}}.
|
|
543
543
|
|
|
544
544
|
@arg point1: Start point (L{LatLon}).
|
|
@@ -546,12 +546,12 @@ class LatLon(LatLonSphericalBase):
|
|
|
546
546
|
@kwarg radius: Mean earth radius (C{meter}).
|
|
547
547
|
@kwarg wrap_adjust_limit: Optional keyword arguments for functions
|
|
548
548
|
L{sphericalTrigonometry.nearestOn3} and
|
|
549
|
-
L{pygeodesy.
|
|
549
|
+
L{pygeodesy.equirectangular4},
|
|
550
550
|
|
|
551
551
|
@return: Closest point on the great circle line (L{LatLon}).
|
|
552
552
|
|
|
553
553
|
@raise LimitError: Lat- and/or longitudinal delta exceeds B{C{limit}},
|
|
554
|
-
see function L{pygeodesy.
|
|
554
|
+
see function L{pygeodesy.equirectangular4}.
|
|
555
555
|
|
|
556
556
|
@raise NotImplementedError: Keyword argument C{B{within}=False}
|
|
557
557
|
is not (yet) supported.
|
|
@@ -560,7 +560,7 @@ class LatLon(LatLonSphericalBase):
|
|
|
560
560
|
|
|
561
561
|
@raise ValueError: Invalid B{C{radius}} or B{C{options}}.
|
|
562
562
|
|
|
563
|
-
@see: Functions L{pygeodesy.
|
|
563
|
+
@see: Functions L{pygeodesy.equirectangular4} and L{pygeodesy.nearestOn5}
|
|
564
564
|
and method L{sphericalTrigonometry.LatLon.nearestOn3}.
|
|
565
565
|
'''
|
|
566
566
|
# remove kwarg B{C{within}} if present
|
|
@@ -605,7 +605,7 @@ class LatLon(LatLonSphericalBase):
|
|
|
605
605
|
def nearestOn3(self, points, closed=False, radius=R_M, **wrap_adjust_limit):
|
|
606
606
|
'''Locate the point on a polygon closest to this point.
|
|
607
607
|
|
|
608
|
-
Distances are approximated by function L{pygeodesy.
|
|
608
|
+
Distances are approximated by function L{pygeodesy.equirectangular4},
|
|
609
609
|
subject to the supplied B{C{options}}.
|
|
610
610
|
|
|
611
611
|
@arg points: The polygon points (L{LatLon}[]).
|
|
@@ -613,17 +613,17 @@ class LatLon(LatLonSphericalBase):
|
|
|
613
613
|
@kwarg radius: Mean earth radius (C{meter}).
|
|
614
614
|
@kwarg wrap_adjust_limit: Optional keyword arguments for function
|
|
615
615
|
L{sphericalTrigonometry.nearestOn3} and
|
|
616
|
-
L{pygeodesy.
|
|
616
|
+
L{pygeodesy.equirectangular4},
|
|
617
617
|
|
|
618
618
|
@return: A L{NearestOn3Tuple}C{(closest, distance, angle)} of the
|
|
619
|
-
C{closest} point (L{LatLon}), the L{pygeodesy.
|
|
619
|
+
C{closest} point (L{LatLon}), the L{pygeodesy.equirectangular4}
|
|
620
620
|
C{distance} between this and the C{closest} point converted to
|
|
621
621
|
C{meter}, same units as B{C{radius}}. The C{angle} from this
|
|
622
622
|
to the C{closest} point is in compass C{degrees360}, like
|
|
623
623
|
function L{pygeodesy.compassAngle}.
|
|
624
624
|
|
|
625
625
|
@raise LimitError: Lat- and/or longitudinal delta exceeds B{C{limit}},
|
|
626
|
-
see function L{pygeodesy.
|
|
626
|
+
see function L{pygeodesy.equirectangular4}.
|
|
627
627
|
|
|
628
628
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
629
629
|
|
|
@@ -631,7 +631,7 @@ class LatLon(LatLonSphericalBase):
|
|
|
631
631
|
|
|
632
632
|
@raise ValueError: Invalid B{C{radius}} or B{C{options}}.
|
|
633
633
|
|
|
634
|
-
@see: Functions L{pygeodesy.compassAngle}, L{pygeodesy.
|
|
634
|
+
@see: Functions L{pygeodesy.compassAngle}, L{pygeodesy.equirectangular4}
|
|
635
635
|
and L{pygeodesy.nearestOn5}.
|
|
636
636
|
'''
|
|
637
637
|
return nearestOn3(self, points, closed=closed, radius=radius,
|
|
@@ -1222,7 +1222,7 @@ def nearestOn3(point, points, closed=False, radius=R_M, wrap=False, adjust=True,
|
|
|
1222
1222
|
limit=9, **LatLon_and_kwds):
|
|
1223
1223
|
'''Locate the point on a path or polygon closest to a reference point.
|
|
1224
1224
|
|
|
1225
|
-
Distances are I{approximated} using function L{pygeodesy.
|
|
1225
|
+
Distances are I{approximated} using function L{pygeodesy.equirectangular4},
|
|
1226
1226
|
subject to the supplied B{C{options}}.
|
|
1227
1227
|
|
|
1228
1228
|
@arg point: The reference point (L{LatLon}).
|
|
@@ -1231,19 +1231,19 @@ def nearestOn3(point, points, closed=False, radius=R_M, wrap=False, adjust=True,
|
|
|
1231
1231
|
@kwarg radius: Mean earth radius (C{meter}).
|
|
1232
1232
|
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
1233
1233
|
B{C{points}} (C{bool}).
|
|
1234
|
-
@kwarg adjust: See function L{pygeodesy.
|
|
1235
|
-
@kwarg limit: See function L{pygeodesy.
|
|
1234
|
+
@kwarg adjust: See function L{pygeodesy.equirectangular4} (C{bool}).
|
|
1235
|
+
@kwarg limit: See function L{pygeodesy.equirectangular4} (C{degrees}),
|
|
1236
1236
|
default C{9 degrees} is about C{1,000 Kmeter} (for mean
|
|
1237
1237
|
spherical earth radius L{R_KM}).
|
|
1238
1238
|
@kwarg LatLon: Optional class to return the closest point (L{LatLon})
|
|
1239
1239
|
or C{None}.
|
|
1240
1240
|
@kwarg options: Optional keyword arguments for function
|
|
1241
|
-
L{pygeodesy.
|
|
1241
|
+
L{pygeodesy.equirectangular4}.
|
|
1242
1242
|
|
|
1243
1243
|
@return: A L{NearestOn3Tuple}C{(closest, distance, angle)} with the
|
|
1244
1244
|
C{closest} point as B{C{LatLon}} or L{LatLon3Tuple}C{(lat,
|
|
1245
1245
|
lon, height)} if B{C{LatLon}} is C{None}. The C{distance}
|
|
1246
|
-
is the L{pygeodesy.
|
|
1246
|
+
is the L{pygeodesy.equirectangular4} distance between the
|
|
1247
1247
|
C{closest} and the given B{C{point}} converted to C{meter},
|
|
1248
1248
|
same units as B{C{radius}}. The C{angle} from the given
|
|
1249
1249
|
B{C{point}} to the C{closest} is in compass C{degrees360},
|
|
@@ -1251,7 +1251,7 @@ def nearestOn3(point, points, closed=False, radius=R_M, wrap=False, adjust=True,
|
|
|
1251
1251
|
the (interpolated) height at the C{closest} point.
|
|
1252
1252
|
|
|
1253
1253
|
@raise LimitError: Lat- and/or longitudinal delta exceeds the B{C{limit}},
|
|
1254
|
-
see function L{pygeodesy.
|
|
1254
|
+
see function L{pygeodesy.equirectangular4}.
|
|
1255
1255
|
|
|
1256
1256
|
@raise PointsError: Insufficient number of B{C{points}}.
|
|
1257
1257
|
|
|
@@ -1259,7 +1259,7 @@ def nearestOn3(point, points, closed=False, radius=R_M, wrap=False, adjust=True,
|
|
|
1259
1259
|
|
|
1260
1260
|
@raise ValueError: Invalid B{C{radius}}.
|
|
1261
1261
|
|
|
1262
|
-
@see: Functions L{pygeodesy.
|
|
1262
|
+
@see: Functions L{pygeodesy.equirectangular4} and L{pygeodesy.nearestOn5}.
|
|
1263
1263
|
'''
|
|
1264
1264
|
t = _nearestOn5(point, points, closed=closed, wrap=wrap,
|
|
1265
1265
|
adjust=adjust, limit=limit)
|
pygeodesy/trf.py
CHANGED
|
@@ -80,8 +80,8 @@ from pygeodesy.interns import MISSING, NN, _AT_, _COMMASPACE_, _conversion_, \
|
|
|
80
80
|
_NAD83_, _no_, _PLUS_, _reframe_, _s_, _SPACE_, \
|
|
81
81
|
_STAR_, _to_, _vs_, _WGS84_, _x_, _intern as _i
|
|
82
82
|
# from pygeodesy.lazily import _ALL_LAZY # from .units
|
|
83
|
-
from pygeodesy.named import ADict, classname, _lazyNamedEnumItem as _lazy,
|
|
84
|
-
_NamedEnum, _NamedEnumItem, _NamedTuple, Fmt, unstr
|
|
83
|
+
from pygeodesy.named import ADict, classname, _lazyNamedEnumItem as _lazy, _name2__, \
|
|
84
|
+
_Named, _NamedEnum, _NamedEnumItem, _NamedTuple, Fmt, unstr
|
|
85
85
|
from pygeodesy.props import deprecated_method, property_doc_, Property_RO, property_RO
|
|
86
86
|
# from pygeodesy.streprs import Fmt, unstr # from .named
|
|
87
87
|
from pygeodesy.units import Epoch, Float, _ALL_LAZY
|
|
@@ -91,7 +91,7 @@ from math import ceil as _ceil, fabs
|
|
|
91
91
|
# import operator as _operator # from .datums
|
|
92
92
|
|
|
93
93
|
__all__ = _ALL_LAZY.trf
|
|
94
|
-
__version__ = '24.05.
|
|
94
|
+
__version__ = '24.05.31'
|
|
95
95
|
|
|
96
96
|
_EP0CH = Epoch(0, low=0)
|
|
97
97
|
_Es = {_EP0CH: _EP0CH} # L{Epoch}s, deleted below
|
|
@@ -405,10 +405,11 @@ class TransformXform(Transform):
|
|
|
405
405
|
n = name or (X.toStr() if X else NN)
|
|
406
406
|
return Transform.rename(self, n)
|
|
407
407
|
|
|
408
|
-
def toRefFrame(self, point, name
|
|
408
|
+
def toRefFrame(self, point, **name): # PYCHOK signature
|
|
409
409
|
'''Convert an ellipsoidal point using this transform and Xform.
|
|
410
410
|
|
|
411
411
|
@arg point: The point to convert (C{Cartesian} or C{LatLon}).
|
|
412
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
412
413
|
|
|
413
414
|
@return: A copy of the B{C{point}}, converted I{directly} to
|
|
414
415
|
this transform's Xform's C{refName2} and C{epoch}.
|
|
@@ -423,7 +424,7 @@ class TransformXform(Transform):
|
|
|
423
424
|
if X: # see _toRefFrame below
|
|
424
425
|
p._reframe = X.reframe2
|
|
425
426
|
p._epoch = X.epoch
|
|
426
|
-
p.rename(
|
|
427
|
+
p.rename(self._name__(name))
|
|
427
428
|
return p
|
|
428
429
|
|
|
429
430
|
def toTransform(self, epoch1, **epoch2_inverse):
|
|
@@ -1043,7 +1044,7 @@ def _sumstr(name1, name2, p_):
|
|
|
1043
1044
|
|
|
1044
1045
|
|
|
1045
1046
|
def _toRefFrame(point, reframe2, reframe=None, epoch=None,
|
|
1046
|
-
epoch2=None,
|
|
1047
|
+
epoch2=None, **name_LatLon_kwds):
|
|
1047
1048
|
'''(INTERNAL) Convert an ellipsoidal point to C{reframe2}
|
|
1048
1049
|
and C{epoch2 or epoch or pont.epoch or reframe.epoch}.
|
|
1049
1050
|
'''
|
|
@@ -1063,6 +1064,7 @@ def _toRefFrame(point, reframe2, reframe=None, epoch=None,
|
|
|
1063
1064
|
_to_, _AT_(reframe2.name, e2))
|
|
1064
1065
|
raise TRFError(_no_(_conversion_), txt=t)
|
|
1065
1066
|
|
|
1067
|
+
name, LatLon_kwds = _name2__(name_LatLon_kwds)
|
|
1066
1068
|
if t0: # is not ()
|
|
1067
1069
|
if t0.isunity:
|
|
1068
1070
|
p = point.dup()
|
|
@@ -1078,7 +1080,7 @@ def _toRefFrame(point, reframe2, reframe=None, epoch=None,
|
|
|
1078
1080
|
p = point.toTransform(t0)
|
|
1079
1081
|
p._reframe = reframe2 # see TRFXform.toRefFrame above
|
|
1080
1082
|
p._epoch = _xattr(t0.Xform, epoch=e2)
|
|
1081
|
-
p.rename(
|
|
1083
|
+
p.rename(reframe2._name__(name))
|
|
1082
1084
|
else:
|
|
1083
1085
|
p = point.dup(_reframe=reframe2, # ditto
|
|
1084
1086
|
_epoch=e2, name=name) if name else point
|
pygeodesy/triaxials.py
CHANGED
|
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
|
|
|
59
59
|
from math import atan2, fabs, sqrt
|
|
60
60
|
|
|
61
61
|
__all__ = _ALL_LAZY.triaxials
|
|
62
|
-
__version__ = '24.05.
|
|
62
|
+
__version__ = '24.05.28'
|
|
63
63
|
|
|
64
64
|
_not_ordered_ = _not_('ordered')
|
|
65
65
|
_omega_ = 'omega'
|
|
@@ -1158,7 +1158,7 @@ def _getitems(items, *indices):
|
|
|
1158
1158
|
return type(items)(map(items.__getitem__, indices))
|
|
1159
1159
|
|
|
1160
1160
|
|
|
1161
|
-
def _hartzell3(pov, los, Tun): # in .
|
|
1161
|
+
def _hartzell3(pov, los, Tun): # in .Ellipsoid.hartzell4, .formy.hartzell
|
|
1162
1162
|
'''(INTERNAL) Hartzell's "Satellite Line-of-Sight Intersection ...",
|
|
1163
1163
|
formula from a Point-Of-View to an I{un-/ordered} Triaxial.
|
|
1164
1164
|
'''
|
pygeodesy/ups.py
CHANGED
|
@@ -26,14 +26,14 @@ from pygeodesy.constants import EPS, EPS0, _EPSmin as _Tol90, \
|
|
|
26
26
|
isnear90, _0_0, _0_5, _1_0, _2_0
|
|
27
27
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
28
28
|
from pygeodesy.dms import degDMS, _neg, parseDMS2
|
|
29
|
-
from pygeodesy.errors import RangeError, _ValueError
|
|
29
|
+
from pygeodesy.errors import RangeError, _ValueError, _xkwds_pop2
|
|
30
30
|
from pygeodesy.fmath import hypot, hypot1, sqrt0
|
|
31
31
|
# from pygeodesy.internals import _under # from .named
|
|
32
32
|
from pygeodesy.interns import NN, _COMMASPACE_, _inside_, _N_, \
|
|
33
33
|
_pole_, _range_, _S_, _scale0_, \
|
|
34
34
|
_SPACE_, _std_, _to_, _UTM_
|
|
35
35
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS, _getenv
|
|
36
|
-
from pygeodesy.named import nameof,
|
|
36
|
+
from pygeodesy.named import nameof, _under
|
|
37
37
|
from pygeodesy.namedTuples import EasNor2Tuple, UtmUps5Tuple, \
|
|
38
38
|
UtmUps8Tuple, UtmUpsLatLon5Tuple
|
|
39
39
|
from pygeodesy.props import deprecated_method, property_doc_, \
|
|
@@ -49,7 +49,7 @@ from pygeodesy.utmupsBase import Fmt, _LLEB, _hemi, _parseUTMUPS5, _to4lldn, \
|
|
|
49
49
|
from math import atan2, fabs, radians, tan
|
|
50
50
|
|
|
51
51
|
__all__ = _ALL_LAZY.ups
|
|
52
|
-
__version__ = '25.05.
|
|
52
|
+
__version__ = '25.05.31'
|
|
53
53
|
|
|
54
54
|
_BZ_UPS = _getenv('PYGEODESY_UPS_POLES', _std_) == _std_
|
|
55
55
|
_Falsing = Meter(2000e3) # false easting and northing (C{meter})
|
|
@@ -57,18 +57,6 @@ _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
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def _scale(E, rho, tau):
|
|
61
|
-
# compute the point scale factor, ala Karney
|
|
62
|
-
t = hypot1(tau)
|
|
63
|
-
return Float(scale=(rho / E.a) * t * sqrt0(E.e21 + E.e2 / t**2))
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def _toBand(lat, lon): # see utm._toBand
|
|
67
|
-
'''(INTERNAL) Get the I{polar} Band letter for a (lat, lon).
|
|
68
|
-
'''
|
|
69
|
-
return _Bands[(0 if lat < 0 else 2) + (0 if -180 < lon < 0 else 1)]
|
|
70
|
-
|
|
71
|
-
|
|
72
60
|
class UPSError(_ValueError):
|
|
73
61
|
'''Universal Polar Stereographic (UPS) parse or other L{Ups} issue.
|
|
74
62
|
'''
|
|
@@ -88,7 +76,7 @@ class Ups(UtmUpsBase):
|
|
|
88
76
|
def __init__(self, zone=0, pole=_N_, easting=_Falsing, # PYCHOK expected
|
|
89
77
|
northing=_Falsing, band=NN, datum=_WGS84,
|
|
90
78
|
falsed=True, gamma=None, scale=None,
|
|
91
|
-
|
|
79
|
+
**name_convergence):
|
|
92
80
|
'''New L{Ups} UPS coordinate.
|
|
93
81
|
|
|
94
82
|
@kwarg zone: UPS zone (C{int}, zero) or zone with/-out I{polar} Band
|
|
@@ -100,13 +88,13 @@ class Ups(UtmUpsBase):
|
|
|
100
88
|
@kwarg band: Optional, I{polar} Band (C{str}, 'A'|'B'|'Y'|'Z').
|
|
101
89
|
@kwarg datum: Optional, this coordinate's datum (L{Datum},
|
|
102
90
|
L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}).
|
|
103
|
-
@kwarg falsed: If C{True}, both B{C{easting}} and B{C{northing}}
|
|
104
|
-
|
|
105
|
-
@kwarg gamma: Optional
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
@kwarg
|
|
109
|
-
|
|
91
|
+
@kwarg falsed: If C{True}, both B{C{easting}} and B{C{northing}} are
|
|
92
|
+
falsed (C{bool}).
|
|
93
|
+
@kwarg gamma: Optional meridian convergence, bearing off grid North,
|
|
94
|
+
clockwise from true North to save (C{degrees}) or C{None}.
|
|
95
|
+
@kwarg scale: Optional grid scale factor to save (C{scalar}) or C{None}.
|
|
96
|
+
@kwarg name_convergence: Optional C{B{name}=NN} (C{str}) and DEPRECATED
|
|
97
|
+
keyword argument C{B{convergence}=None}, use B{C{gamma}}.
|
|
110
98
|
|
|
111
99
|
@raise TypeError: Invalid B{C{datum}}.
|
|
112
100
|
|
|
@@ -114,18 +102,19 @@ class Ups(UtmUpsBase):
|
|
|
114
102
|
B{C{northing}}, B{C{band}}, B{C{convergence}}
|
|
115
103
|
or B{C{scale}}.
|
|
116
104
|
'''
|
|
117
|
-
if
|
|
118
|
-
|
|
119
|
-
|
|
105
|
+
if name_convergence:
|
|
106
|
+
gamma, name = _xkwds_pop2(name_convergence, convergence=gamma)
|
|
107
|
+
if name:
|
|
108
|
+
self.name = name
|
|
120
109
|
try:
|
|
121
|
-
z, B,
|
|
110
|
+
z, B, self._pole = _to3zBhp(zone, band, hemipole=pole)
|
|
122
111
|
if z != _UPS_ZONE or (B and (B not in _Bands)):
|
|
123
112
|
raise ValueError
|
|
124
113
|
except (TypeError, ValueError) as x:
|
|
125
114
|
raise UPSError(zone=zone, pole=pole, band=band, cause=x)
|
|
126
|
-
|
|
115
|
+
|
|
127
116
|
UtmUpsBase.__init__(self, easting, northing, band=B, datum=datum, falsed=falsed,
|
|
128
|
-
|
|
117
|
+
gamma=gamma, scale=scale)
|
|
129
118
|
|
|
130
119
|
def __eq__(self, other):
|
|
131
120
|
return isinstance(other, Ups) and other.zone == self.zone \
|
|
@@ -161,13 +150,11 @@ class Ups(UtmUpsBase):
|
|
|
161
150
|
f = _Falsing if self.falsed else 0
|
|
162
151
|
return EasNor2Tuple(f, f)
|
|
163
152
|
|
|
164
|
-
def parse(self, strUPS, name
|
|
153
|
+
def parse(self, strUPS, **name):
|
|
165
154
|
'''Parse a string to a similar L{Ups} instance.
|
|
166
155
|
|
|
167
|
-
@arg strUPS: The UPS coordinate (C{str}),
|
|
168
|
-
|
|
169
|
-
@kwarg name: Optional instance name (C{str}),
|
|
170
|
-
overriding this name.
|
|
156
|
+
@arg strUPS: The UPS coordinate (C{str}), see function L{parseUPS5}.
|
|
157
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}), overriding this name.
|
|
171
158
|
|
|
172
159
|
@return: The similar instance (L{Ups}).
|
|
173
160
|
|
|
@@ -176,7 +163,7 @@ class Ups(UtmUpsBase):
|
|
|
176
163
|
@see: Functions L{parseUTM5} and L{pygeodesy.parseUTMUPS5}.
|
|
177
164
|
'''
|
|
178
165
|
return parseUPS5(strUPS, datum=self.datum, Ups=self.classof,
|
|
179
|
-
|
|
166
|
+
name=self._name__(name))
|
|
180
167
|
|
|
181
168
|
@deprecated_method
|
|
182
169
|
def parseUPS(self, strUPS): # PYCHOK no cover
|
|
@@ -250,9 +237,8 @@ class Ups(UtmUpsBase):
|
|
|
250
237
|
b, g, a = atan2(x, y), -1, _neg(a)
|
|
251
238
|
ll = _LLEB(a, degrees180(b), datum=self._datum, name=self.name)
|
|
252
239
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
self._latlon5args(ll, _toBand, unfalse)
|
|
240
|
+
k = _scale(E, r, t) if r > 0 else self.scale0
|
|
241
|
+
self._latlon5args(ll, g * b, k, _toBand, unfalse)
|
|
256
242
|
|
|
257
243
|
def toRepr(self, prec=0, fmt=Fmt.SQUARE, sep=_COMMASPACE_, B=False, cs=False, **unused): # PYCHOK expected
|
|
258
244
|
'''Return a string representation of this UPS coordinate.
|
|
@@ -353,7 +339,7 @@ class _Ups_K1(Ups):
|
|
|
353
339
|
_scale0 = _K1_UPS
|
|
354
340
|
|
|
355
341
|
|
|
356
|
-
def parseUPS5(strUPS, datum=_WGS84, Ups=Ups, falsed=True, name
|
|
342
|
+
def parseUPS5(strUPS, datum=_WGS84, Ups=Ups, falsed=True, **name):
|
|
357
343
|
'''Parse a string representing a UPS coordinate, consisting of
|
|
358
344
|
C{"[zone][band] pole easting northing"} where B{C{zone}} is
|
|
359
345
|
pseudo zone C{"00"|"0"|""} and C{band} is C{'A'|'B'|'Y'|'Z'|''}.
|
|
@@ -362,8 +348,9 @@ def parseUPS5(strUPS, datum=_WGS84, Ups=Ups, falsed=True, name=NN):
|
|
|
362
348
|
@kwarg datum: Optional datum to use (L{Datum}).
|
|
363
349
|
@kwarg Ups: Optional class to return the UPS coordinate (L{Ups})
|
|
364
350
|
or C{None}.
|
|
365
|
-
@kwarg falsed:
|
|
366
|
-
|
|
351
|
+
@kwarg falsed: If C{True}, both B{C{easting}} and B{C{northing}}
|
|
352
|
+
are falsed (C{bool}).
|
|
353
|
+
@kwarg name: Optional B{C{Ups}} C{B{name}=NN} (C{str}).
|
|
367
354
|
|
|
368
355
|
@return: The UPS coordinate (B{C{Ups}}) or a
|
|
369
356
|
L{UtmUps5Tuple}C{(zone, hemipole, easting, northing,
|
|
@@ -376,43 +363,54 @@ def parseUPS5(strUPS, datum=_WGS84, Ups=Ups, falsed=True, name=NN):
|
|
|
376
363
|
if z != _UPS_ZONE or (B and B not in _Bands):
|
|
377
364
|
raise UPSError(strUPS=strUPS, zone=z, band=B)
|
|
378
365
|
|
|
379
|
-
r = UtmUps5Tuple(z, p, e, n, B, Error=UPSError) if Ups is None \
|
|
380
|
-
else Ups(z, p, e, n, band=B, falsed=falsed, datum=datum)
|
|
381
|
-
return
|
|
366
|
+
r = UtmUps5Tuple(z, p, e, n, B, Error=UPSError, **name) if Ups is None \
|
|
367
|
+
else Ups(z, p, e, n, band=B, falsed=falsed, datum=datum, **name)
|
|
368
|
+
return r
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def _scale(E, rho, tau):
|
|
372
|
+
# compute the point scale factor, ala Karney
|
|
373
|
+
t = hypot1(tau)
|
|
374
|
+
return Float(scale=(rho / E.a) * t * sqrt0(E.e21 + E.e2 / t**2))
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def _toBand(lat, lon): # see utm._toBand
|
|
378
|
+
'''(INTERNAL) Get the I{polar} Band letter for a (lat, lon).
|
|
379
|
+
'''
|
|
380
|
+
return _Bands[(0 if lat < 0 else 2) + (0 if -180 < lon < 0 else 1)]
|
|
382
381
|
|
|
383
382
|
|
|
384
383
|
def toUps8(latlon, lon=None, datum=None, Ups=Ups, pole=NN,
|
|
385
|
-
falsed=True, strict=True, name
|
|
384
|
+
falsed=True, strict=True, **name):
|
|
386
385
|
'''Convert a lat-/longitude point to a UPS coordinate.
|
|
387
386
|
|
|
388
|
-
@arg latlon: Latitude (C{degrees}) or an (ellipsoidal)
|
|
389
|
-
|
|
387
|
+
@arg latlon: Latitude (C{degrees}) or an (ellipsoidal) geodetic
|
|
388
|
+
C{LatLon} point.
|
|
390
389
|
@kwarg lon: Optional longitude (C{degrees}) or C{None} if
|
|
391
390
|
B{C{latlon}} is a C{LatLon}.
|
|
392
|
-
@kwarg datum: Optional datum for this UPS coordinate,
|
|
393
|
-
|
|
394
|
-
L{
|
|
395
|
-
@kwarg Ups: Optional class to return the UPS coordinate
|
|
396
|
-
|
|
391
|
+
@kwarg datum: Optional datum for this UPS coordinate, overriding
|
|
392
|
+
B{C{latlon}}'s datum (C{Datum}, L{Ellipsoid},
|
|
393
|
+
L{Ellipsoid2} or L{a_f2Tuple}).
|
|
394
|
+
@kwarg Ups: Optional class to return the UPS coordinate (L{Ups})
|
|
395
|
+
or C{None}.
|
|
397
396
|
@kwarg pole: Optional top/center of (stereographic) projection
|
|
398
397
|
(C{str}, C{'N[orth]'} or C{'S[outh]'}).
|
|
399
|
-
@kwarg falsed:
|
|
398
|
+
@kwarg falsed: If C{True}, false both easting and northing (C{bool}).
|
|
400
399
|
@kwarg strict: Restrict B{C{lat}} to UPS ranges (C{bool}).
|
|
401
|
-
@kwarg name: Optional B{C{Ups}} name (C{str}).
|
|
400
|
+
@kwarg name: Optional B{C{Ups}} C{B{name}=NN} (C{str}).
|
|
402
401
|
|
|
403
|
-
@return: The UPS coordinate (B{C{Ups}}) or a
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
projection top/center.
|
|
402
|
+
@return: The UPS coordinate (B{C{Ups}}) or a L{UtmUps8Tuple}C{(zone,
|
|
403
|
+
hemipole, easting, northing, band, datum, gamma, scale)} if
|
|
404
|
+
B{C{Ups}} is C{None}. The C{hemipole} is the C{'N'|'S'}
|
|
405
|
+
pole, the UPS projection top/center.
|
|
408
406
|
|
|
409
407
|
@raise RangeError: If B{C{strict}} and B{C{lat}} outside the valid
|
|
410
408
|
UPS bands or if B{C{lat}} or B{C{lon}} outside
|
|
411
409
|
the valid range and L{pygeodesy.rangerrors} set
|
|
412
410
|
to C{True}.
|
|
413
411
|
|
|
414
|
-
@raise TypeError: If B{C{latlon}} is not ellipsoidal or
|
|
415
|
-
|
|
412
|
+
@raise TypeError: If B{C{latlon}} is not ellipsoidal or if B{C{datum}}
|
|
413
|
+
is invalid.
|
|
416
414
|
|
|
417
415
|
@raise ValueError: If B{C{lon}} value is missing or if B{C{latlon}}
|
|
418
416
|
is invalid.
|
|
@@ -463,9 +461,7 @@ def toUps8(latlon, lon=None, datum=None, Ups=Ups, pole=NN,
|
|
|
463
461
|
r = Ups(z, p, x, y, band=B, datum=d, falsed=falsed,
|
|
464
462
|
gamma=g, scale=k, name=n)
|
|
465
463
|
if isinstance(latlon, _LLEB) and d is latlon.datum: # see utm._toXtm8
|
|
466
|
-
r._latlon5args(latlon, _toBand, falsed) # XXX weakref(latlon)?
|
|
467
|
-
latlon._gamma = g
|
|
468
|
-
latlon._scale = k
|
|
464
|
+
r._latlon5args(latlon, g, k, _toBand, falsed) # XXX weakref(latlon)?
|
|
469
465
|
else:
|
|
470
466
|
r._hemisphere = _hemi(lat)
|
|
471
467
|
if not r._band:
|
|
@@ -473,18 +469,18 @@ def toUps8(latlon, lon=None, datum=None, Ups=Ups, pole=NN,
|
|
|
473
469
|
return r
|
|
474
470
|
|
|
475
471
|
|
|
476
|
-
def upsZoneBand5(lat, lon, strict=True, name
|
|
472
|
+
def upsZoneBand5(lat, lon, strict=True, **name):
|
|
477
473
|
'''Return the UTM/UPS zone number, I{polar} Band letter, pole and
|
|
478
474
|
clipped lat- and longitude for a given location.
|
|
479
475
|
|
|
480
476
|
@arg lat: Latitude in degrees (C{scalar} or C{str}).
|
|
481
477
|
@arg lon: Longitude in degrees (C{scalar} or C{str}).
|
|
482
478
|
@kwarg strict: Restrict B{C{lat}} to UPS ranges (C{bool}).
|
|
483
|
-
@kwarg name: Optional name (C{str}).
|
|
479
|
+
@kwarg name: Optional B{C{Ups}} C{B{name}=NN} (C{str}).
|
|
484
480
|
|
|
485
|
-
@return: A L{UtmUpsLatLon5Tuple}C{(zone, band, hemipole,
|
|
486
|
-
|
|
487
|
-
|
|
481
|
+
@return: A L{UtmUpsLatLon5Tuple}C{(zone, band, hemipole, lat,
|
|
482
|
+
lon)} where C{hemipole} is the C{'N'|'S'} pole, the
|
|
483
|
+
UPS projection top/center and C{lon} [-180..180).
|
|
488
484
|
|
|
489
485
|
@note: The C{lon} is set to C{0} if B{C{lat}} is C{-90} or
|
|
490
486
|
C{90}, see env variable C{PYGEODESY_UPS_POLES} in
|
|
@@ -514,7 +510,7 @@ def upsZoneBand5(lat, lon, strict=True, name=NN):
|
|
|
514
510
|
|
|
515
511
|
else:
|
|
516
512
|
B, p = NN, _hemi(lat)
|
|
517
|
-
return UtmUpsLatLon5Tuple(z, B, p, lat, lon, Error=UPSError, name
|
|
513
|
+
return UtmUpsLatLon5Tuple(z, B, p, lat, lon, Error=UPSError, **name)
|
|
518
514
|
|
|
519
515
|
# **) MIT License
|
|
520
516
|
#
|
pygeodesy/utily.py
CHANGED
|
@@ -17,7 +17,7 @@ from pygeodesy.constants import EPS, EPS0, INF, NAN, PI, PI2, PI_2, R_M, \
|
|
|
17
17
|
_N_180_0, _360_0, _400_0, _copysign_0_0, \
|
|
18
18
|
_float as _F, _isfinite, isnan, isnear0, \
|
|
19
19
|
_over, _umod_360, _umod_PI2
|
|
20
|
-
from pygeodesy.errors import _ValueError, _xkwds,
|
|
20
|
+
from pygeodesy.errors import _ValueError, _xkwds, _xkwds_get1, _ALL_LAZY, _MODS
|
|
21
21
|
from pygeodesy.internals import _passargs # , _MODS?
|
|
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
|
|
@@ -27,7 +27,7 @@ from pygeodesy.units import Degrees, Degrees_, Feet, Float, Lam, Lam_, \
|
|
|
27
27
|
from math import acos, asin, atan2, cos, degrees, fabs, radians, sin, tan # pow
|
|
28
28
|
|
|
29
29
|
__all__ = _ALL_LAZY.utily
|
|
30
|
-
__version__ = '24.05.
|
|
30
|
+
__version__ = '24.05.29'
|
|
31
31
|
|
|
32
32
|
# read constant name "_M_Unit" as "meter per Unit"
|
|
33
33
|
_M_CHAIN = _F( 20.1168) # yard2m(1) * 22
|
|
@@ -763,7 +763,7 @@ def sincos2d(deg, **adeg):
|
|
|
763
763
|
q -= 1
|
|
764
764
|
d = deg - q * _90_0
|
|
765
765
|
if adeg:
|
|
766
|
-
t =
|
|
766
|
+
t = _xkwds_get1(adeg, adeg=_0_0)
|
|
767
767
|
d = _MODS.karney._around(d + t)
|
|
768
768
|
t = _sin0cos2(q & 3, radians(d), deg)
|
|
769
769
|
else:
|