pygeodesy 24.6.1__py2.py3-none-any.whl → 24.6.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.1.dist-info → PyGeodesy-24.6.24.dist-info}/METADATA +2 -2
- PyGeodesy-24.6.24.dist-info/RECORD +117 -0
- pygeodesy/__init__.py +33 -32
- pygeodesy/albers.py +2 -2
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/auxAngle.py +40 -39
- pygeodesy/auxilats/auxDLat.py +3 -2
- pygeodesy/auxilats/auxLat.py +16 -18
- pygeodesy/auxilats/auxily.py +1 -1
- pygeodesy/azimuthal.py +10 -10
- pygeodesy/basics.py +9 -1
- pygeodesy/booleans.py +53 -66
- pygeodesy/cartesianBase.py +143 -155
- pygeodesy/css.py +14 -18
- pygeodesy/datums.py +6 -6
- pygeodesy/deprecated/__init__.py +1 -1
- pygeodesy/deprecated/classes.py +16 -2
- pygeodesy/deprecated/datum.py +3 -3
- pygeodesy/deprecated/functions.py +6 -8
- pygeodesy/dms.py +23 -27
- pygeodesy/ecef.py +49 -55
- pygeodesy/elevations.py +4 -4
- pygeodesy/ellipsoidalBase.py +28 -70
- pygeodesy/ellipsoidalBaseDI.py +19 -23
- pygeodesy/ellipsoidalExact.py +3 -3
- pygeodesy/ellipsoidalGeodSolve.py +15 -23
- pygeodesy/ellipsoidalKarney.py +37 -60
- pygeodesy/ellipsoidalNvector.py +44 -50
- pygeodesy/ellipsoidalVincenty.py +11 -14
- pygeodesy/ellipsoids.py +107 -101
- pygeodesy/errors.py +101 -49
- pygeodesy/etm.py +32 -44
- pygeodesy/formy.py +55 -58
- pygeodesy/frechet.py +20 -23
- pygeodesy/fsums.py +4 -4
- pygeodesy/gars.py +3 -4
- pygeodesy/geodesici.py +909 -0
- pygeodesy/geodesicw.py +11 -13
- pygeodesy/geodesicx/__init__.py +4 -4
- pygeodesy/geodesicx/gx.py +18 -28
- pygeodesy/geodesicx/gxbases.py +20 -8
- pygeodesy/geodesicx/gxline.py +16 -22
- pygeodesy/geodsolve.py +102 -34
- pygeodesy/geohash.py +39 -60
- pygeodesy/geoids.py +28 -37
- pygeodesy/hausdorff.py +21 -23
- pygeodesy/heights.py +15 -28
- pygeodesy/internals.py +19 -12
- pygeodesy/interns.py +4 -10
- pygeodesy/iters.py +2 -2
- pygeodesy/karney.py +20 -4
- pygeodesy/ktm.py +13 -16
- pygeodesy/latlonBase.py +202 -191
- pygeodesy/lazily.py +96 -59
- pygeodesy/lcc.py +29 -32
- pygeodesy/ltp.py +43 -24
- pygeodesy/ltpTuples.py +190 -183
- pygeodesy/mgrs.py +35 -9
- pygeodesy/named.py +106 -72
- pygeodesy/namedTuples.py +43 -14
- pygeodesy/nvectorBase.py +23 -27
- pygeodesy/osgr.py +9 -9
- pygeodesy/points.py +7 -7
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +5 -5
- pygeodesy/rhumb/bases.py +30 -31
- pygeodesy/rhumb/ekx.py +3 -4
- pygeodesy/rhumb/solve.py +8 -61
- pygeodesy/solveBase.py +22 -19
- pygeodesy/sphericalBase.py +26 -21
- pygeodesy/sphericalNvector.py +13 -13
- pygeodesy/sphericalTrigonometry.py +86 -97
- pygeodesy/streprs.py +8 -36
- pygeodesy/trf.py +3 -3
- pygeodesy/triaxials.py +117 -91
- pygeodesy/units.py +229 -321
- pygeodesy/unitsBase.py +116 -108
- pygeodesy/ups.py +26 -31
- pygeodesy/utily.py +12 -11
- pygeodesy/utm.py +35 -40
- pygeodesy/utmups.py +43 -46
- pygeodesy/utmupsBase.py +9 -10
- pygeodesy/vector3d.py +59 -62
- pygeodesy/vector3dBase.py +17 -15
- pygeodesy/webmercator.py +19 -21
- pygeodesy/wgrs.py +18 -20
- PyGeodesy-24.6.1.dist-info/RECORD +0 -116
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.6.1.dist-info → PyGeodesy-24.6.24.dist-info}/top_level.txt +0 -0
pygeodesy/osgr.py
CHANGED
|
@@ -46,14 +46,14 @@ from pygeodesy.namedTuples import EasNor2Tuple, LatLon2Tuple, \
|
|
|
46
46
|
from pygeodesy.props import Property_RO, property_RO
|
|
47
47
|
from pygeodesy.streprs import _EN_WIDE, enstr2, _enstr2m3, Fmt, \
|
|
48
48
|
_resolution10, unstr, _xzipairs
|
|
49
|
-
from pygeodesy.units import Easting,
|
|
50
|
-
|
|
49
|
+
from pygeodesy.units import Easting, Lamd, Lat, Lon, Northing, \
|
|
50
|
+
Phid, Scalar, _10um, _100km
|
|
51
51
|
from pygeodesy.utily import degrees90, degrees180, sincostan3, truncate
|
|
52
52
|
|
|
53
53
|
from math import cos, fabs, radians, sin, sqrt
|
|
54
54
|
|
|
55
55
|
__all__ = _ALL_LAZY.osgr
|
|
56
|
-
__version__ = '24.
|
|
56
|
+
__version__ = '24.06.15'
|
|
57
57
|
|
|
58
58
|
_equivalent_ = 'equivalent'
|
|
59
59
|
_OSGR_ = 'OSGR'
|
|
@@ -108,7 +108,7 @@ class _NG(object):
|
|
|
108
108
|
|
|
109
109
|
@Property_RO
|
|
110
110
|
def lam0(self): # True origin longitude C{radians}
|
|
111
|
-
return
|
|
111
|
+
return Lamd(self.lon0)
|
|
112
112
|
|
|
113
113
|
@Property_RO
|
|
114
114
|
def lat0(self): # True origin latitude, 49°N
|
|
@@ -160,7 +160,7 @@ class _NG(object):
|
|
|
160
160
|
|
|
161
161
|
@Property_RO
|
|
162
162
|
def phi0(self): # True origin latitude C{radians}
|
|
163
|
-
return
|
|
163
|
+
return Phid(self.lat0)
|
|
164
164
|
|
|
165
165
|
def reverse(self, osgr): # convert C{osgr} to (ellipsoidal} LatLon, as I{Karney}'s
|
|
166
166
|
# U{Reverse<https://GeographicLib.SourceForge.io/C++/doc/OSGB_8hpp_source.html>}
|
|
@@ -296,7 +296,7 @@ class Osgr(_NamedBase):
|
|
|
296
296
|
@kwarg LatLon_kwds: Optional, additional B{C{LatLon}} keyword
|
|
297
297
|
arguments, ignored if C{B{LatLon} is None}.
|
|
298
298
|
|
|
299
|
-
@return: A B{C{LatLon}} instance or if B{
|
|
299
|
+
@return: A B{C{LatLon}} instance or if C{B{LatLon} is None}
|
|
300
300
|
a L{LatLonDatum3Tuple}C{(lat, lon, datum)}.
|
|
301
301
|
|
|
302
302
|
@note: While OS grid references are based on the OSGB36 datum,
|
|
@@ -520,8 +520,8 @@ def parseOSGR(strOSGR, Osgr=Osgr, **name_Osgr_kwds):
|
|
|
520
520
|
optional, additional B{C{Osgr}} keyword arguments,
|
|
521
521
|
ignored if C{B{Osgr} is None}.
|
|
522
522
|
|
|
523
|
-
@return: An (B{C{Osgr}}) instance or if B{
|
|
524
|
-
|
|
523
|
+
@return: An (B{C{Osgr}}) instance or if C{B{Osgr} is None}, an
|
|
524
|
+
L{EasNor2Tuple}C{(easting, northing)}.
|
|
525
525
|
|
|
526
526
|
@raise OSGRError: Invalid B{C{strOSGR}}.
|
|
527
527
|
'''
|
|
@@ -598,7 +598,7 @@ def toOsgr(latlon, lon=None, kTM=False, datum=_WGS84, Osgr=Osgr, # MCCABE 14
|
|
|
598
598
|
and additional B{C{Osgr}} keyword arguments,
|
|
599
599
|
ignored if C{B{Osgr} is None}.
|
|
600
600
|
|
|
601
|
-
@return: An (B{C{Osgr}}) instance or if B{
|
|
601
|
+
@return: An (B{C{Osgr}}) instance or if C{B{Osgr} is None}
|
|
602
602
|
an L{EasNor2Tuple}C{(easting, northing)}.
|
|
603
603
|
|
|
604
604
|
@note: If L{isint}C{(B{prec})} both easting and northing are
|
pygeodesy/points.py
CHANGED
|
@@ -62,7 +62,7 @@ from pygeodesy.utily import atan2b, degrees90, degrees180, degrees2m, \
|
|
|
62
62
|
from math import cos, fabs, fmod as _fmod, radians, sin
|
|
63
63
|
|
|
64
64
|
__all__ = _ALL_LAZY.points
|
|
65
|
-
__version__ = '24.
|
|
65
|
+
__version__ = '24.06.15'
|
|
66
66
|
|
|
67
67
|
_ilat_ = 'ilat'
|
|
68
68
|
_ilon_ = 'ilon'
|
|
@@ -391,7 +391,7 @@ class _Array2LatLon(_Basequence): # immutable, on purpose
|
|
|
391
391
|
# check the attr indices
|
|
392
392
|
for n, (ai, i) in enumerate(ais):
|
|
393
393
|
if not isint(i):
|
|
394
|
-
raise _IsnotError(int
|
|
394
|
+
raise _IsnotError(int, **{ai: i})
|
|
395
395
|
i = int(i)
|
|
396
396
|
if not 0 <= i < shape[1]:
|
|
397
397
|
raise _ValueError(ai, i)
|
|
@@ -959,8 +959,8 @@ def areaOf(points, adjust=True, radius=R_M, wrap=True):
|
|
|
959
959
|
the B{C{points}} (C{bool}).
|
|
960
960
|
|
|
961
961
|
@return: Approximate area (I{square} C{meter}, same units as
|
|
962
|
-
B{C{radius}} or C{radians} I{squared} if B{
|
|
963
|
-
is
|
|
962
|
+
B{C{radius}} or C{radians} I{squared} if C{B{radius}
|
|
963
|
+
is None}).
|
|
964
964
|
|
|
965
965
|
@raise PointsError: Insufficient number of B{C{points}}
|
|
966
966
|
|
|
@@ -992,8 +992,8 @@ def boundsOf(points, wrap=False, LatLon=None): # was=True
|
|
|
992
992
|
@kwarg LatLon: Optional class to return the C{bounds}
|
|
993
993
|
corners (C{LatLon}) or C{None}.
|
|
994
994
|
|
|
995
|
-
@return: A L{Bounds2Tuple}C{(latlonSW, latlonNE)}
|
|
996
|
-
B{C{LatLon}}
|
|
995
|
+
@return: A L{Bounds2Tuple}C{(latlonSW, latlonNE)}, each
|
|
996
|
+
a B{C{LatLon}} or if C{B{LatLon} is None}, a
|
|
997
997
|
L{Bounds4Tuple}C{(latS, lonW, latN, lonE)}.
|
|
998
998
|
|
|
999
999
|
@raise PointsError: Insufficient number of B{C{points}}
|
|
@@ -1479,7 +1479,7 @@ def nearestOn5(point, points, closed=False, wrap=False, adjust=True,
|
|
|
1479
1479
|
spherical earth radius L{R_KM}).
|
|
1480
1480
|
@kwarg LatLon_and_kwds: Optional, C{B{LatLon}=None} class to use for
|
|
1481
1481
|
the closest point and additional B{C{LatLon}} keyword
|
|
1482
|
-
arguments, ignored if C{B{LatLon}
|
|
1482
|
+
arguments, ignored if C{B{LatLon} is None} or not given.
|
|
1483
1483
|
|
|
1484
1484
|
@return: A L{NearestOn3Tuple}C{(closest, distance, angle)} with the
|
|
1485
1485
|
{closest} point (B{C{LatLon}}) or if C{B{LatLon} is None},
|
pygeodesy/rhumb/__init__.py
CHANGED
|
@@ -9,7 +9,7 @@ u'''Package of lazily imported C{rhumb} modules L{rhumb.aux_}, L{rhumb.ekx} and
|
|
|
9
9
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER, _lazy_import_as, _unLazy0
|
|
10
10
|
|
|
11
11
|
__all__ = _ALL_LAZY.rhumb
|
|
12
|
-
__version__ = '24.
|
|
12
|
+
__version__ = '24.06.18'
|
|
13
13
|
|
|
14
14
|
if _unLazy0: # or _isfrozen
|
|
15
15
|
from pygeodesy.rhumb.aux_ import RhumbAux, RhumbLineAux
|
pygeodesy/rhumb/aux_.py
CHANGED
|
@@ -47,7 +47,7 @@ from pygeodesy.rhumb.bases import RhumbBase, RhumbLineBase, \
|
|
|
47
47
|
from math import ceil as _ceil, fabs, radians
|
|
48
48
|
|
|
49
49
|
__all__ = _ALL_LAZY.rhumb_aux_
|
|
50
|
-
__version__ = '24.
|
|
50
|
+
__version__ = '24.06.11'
|
|
51
51
|
|
|
52
52
|
# DIGITS = (sizeof(real) * 8) bits
|
|
53
53
|
# = (ctypes.sizeof(ctypes.c_double(1.0)) * 8) bits
|
|
@@ -74,14 +74,14 @@ class RhumbAux(RhumbBase):
|
|
|
74
74
|
@kwarg a_earth: This rhumb's earth model (L{Datum}, L{Ellipsoid},
|
|
75
75
|
L{Ellipsoid2}, L{a_f2Tuple}, 2-tuple C{(a, f)}) or
|
|
76
76
|
the (equatorial) radius (C{meter}, conventionally).
|
|
77
|
-
@kwarg f: The ellipsoid's flattening (C{scalar}),
|
|
78
|
-
C{scalar}, ignored otherwise.
|
|
77
|
+
@kwarg f: The ellipsoid's flattening (C{scalar}), required if B{C{a_earth}}
|
|
78
|
+
is C{scalar}, ignored otherwise.
|
|
79
79
|
@kwarg exact: If C{True}, use the exact expressions for the I{Auxiliary
|
|
80
80
|
Latitudes}, otherwise use the I{Fourier} series expansion
|
|
81
81
|
(C{bool}), see also property C{exact}.
|
|
82
82
|
@kwarg TMorder_name: Optional C{B{name}=NN} (C{str}) and optional
|
|
83
|
-
keyword argument C{B{TMorder}=6}
|
|
84
|
-
|
|
83
|
+
keyword argument C{B{TMorder}=6}, the order of the
|
|
84
|
+
L{KTransverseMercator}, see property C{TMorder}.
|
|
85
85
|
|
|
86
86
|
@raise ImportError: Package C{numpy} not found or not installed, only
|
|
87
87
|
required for area C{S12} when C{B{exact} is True}.
|
pygeodesy/rhumb/bases.py
CHANGED
|
@@ -52,11 +52,11 @@ from pygeodesy.vector3d import _intersect3d3, Vector3d # in .Intersection below
|
|
|
52
52
|
from math import cos, fabs
|
|
53
53
|
|
|
54
54
|
__all__ = ()
|
|
55
|
-
__version__ = '24.
|
|
55
|
+
__version__ = '24.06.18'
|
|
56
56
|
|
|
57
57
|
_anti_ = _Dash('anti')
|
|
58
58
|
_rls = [] # instances of C{RbumbLine...} to be updated
|
|
59
|
-
_TRIPS =
|
|
59
|
+
_TRIPS = 129 # .Intersection, .PlumbTo, 19+
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
class _Lat(Lat):
|
|
@@ -716,7 +716,7 @@ class RhumbLineBase(_CapsBase):
|
|
|
716
716
|
t = _xTMr(v.x, v.y, lon0=p.lon) # PYCHOK Reverse4Tuple
|
|
717
717
|
d = _diff(t.lon - p.lon, t.lat) # PYCHOK t.lat + p.lat - p.lat
|
|
718
718
|
p = _LL2T(t.lat + p.lat, t.lon) # PYCHOK t.lon + p.lon = lon0
|
|
719
|
-
if d < tol: # 19 trips
|
|
719
|
+
if d < tol: # 19+ trips
|
|
720
720
|
break
|
|
721
721
|
else:
|
|
722
722
|
raise ValueError(Fmt.no_convergence(d, tol))
|
|
@@ -724,7 +724,7 @@ class RhumbLineBase(_CapsBase):
|
|
|
724
724
|
P = GDict(lat1=self.lat1, lat2=p.lat, lat0=other.lat1,
|
|
725
725
|
lon1=self.lon1, lon2=p.lon, lon0=other.lon1,
|
|
726
726
|
name=_dunder_nameof(self.Intersection, self.name))
|
|
727
|
-
r =
|
|
727
|
+
r = self.Inverse(p.lat, p.lon, outmask=Caps.DISTANCE)
|
|
728
728
|
t = other.Inverse(p.lat, p.lon, outmask=Caps.DISTANCE)
|
|
729
729
|
P.set_(azi12= self.azi12, a12=r.a12, s12=r.s12,
|
|
730
730
|
azi02=other.azi12, a02=t.a12, s02=t.s12,
|
|
@@ -824,9 +824,9 @@ class RhumbLineBase(_CapsBase):
|
|
|
824
824
|
@kwarg exact: If C{None}, use a rhumb line perpendicular to this rhumb line,
|
|
825
825
|
otherwise use an I{exact} C{Geodesic...} from the given point
|
|
826
826
|
perpendicular to this rhumb line (C{bool} or C{Geodesic...}),
|
|
827
|
-
see method L{Ellipsoid.geodesic_}.
|
|
828
|
-
@kwarg eps: Optional tolerance
|
|
829
|
-
|
|
827
|
+
see method L{geodesic_<pygeodesy.Ellipsoid.geodesic_>}.
|
|
828
|
+
@kwarg eps: Optional tolerance (C{EPS}), used only if C{B{exact} is None},
|
|
829
|
+
see function L{intersection3d3<pygeodesy.intersection3d3>}.
|
|
830
830
|
@kwarg est: Optionally, an initial estimate for the distance C{s12} of the
|
|
831
831
|
intersection I{along} this rhumb line (C{meter}), used only if
|
|
832
832
|
C{B{exact} is not None}.
|
|
@@ -849,11 +849,11 @@ class RhumbLineBase(_CapsBase):
|
|
|
849
849
|
<https://PyPI.org/project/geographiclib>}
|
|
850
850
|
package not found or not installed.
|
|
851
851
|
|
|
852
|
-
@raise IntersectionError: No convergence for this B{C{eps}} or
|
|
853
|
-
intersection for some other reason.
|
|
852
|
+
@raise IntersectionError: No convergence for this B{C{eps}} or B{C{tol}} or
|
|
853
|
+
no intersection for some other reason.
|
|
854
854
|
|
|
855
|
-
@see: Methods C{distance2}, C{Intersecant2} and C{Intersection}
|
|
856
|
-
|
|
855
|
+
@see: Methods C{distance2}, C{Intersecant2} and C{Intersection} and function
|
|
856
|
+
L{intersection3d3<pygeodesy.intersection3d3>}.
|
|
857
857
|
'''
|
|
858
858
|
Cs, tol = Caps, Float_(tol=tol, low=EPS, high=None)
|
|
859
859
|
|
|
@@ -899,7 +899,7 @@ class RhumbLineBase(_CapsBase):
|
|
|
899
899
|
lat0=lat0, lon0=lon0, iteration=i, at=r.azi2 - self.azi12,
|
|
900
900
|
name=_dunder_nameof(self.PlumbTo, self.name))
|
|
901
901
|
except Exception as x: # Fsum(NAN) Value-, ZeroDivisionError
|
|
902
|
-
raise IntersectionError(lat0, lon0, tol=tol, exact=exact,
|
|
902
|
+
raise IntersectionError(lat0=lat0, lon0=lon0, tol=tol, exact=exact,
|
|
903
903
|
eps=eps, est=est, iteration=i, cause=x)
|
|
904
904
|
|
|
905
905
|
return P
|
|
@@ -907,29 +907,28 @@ class RhumbLineBase(_CapsBase):
|
|
|
907
907
|
def Position(self, s12, outmask=Caps.LATITUDE_LONGITUDE):
|
|
908
908
|
'''Compute a point at a given distance on this rhumb line.
|
|
909
909
|
|
|
910
|
-
@arg s12: The distance along this rhumb line from its origin to
|
|
911
|
-
|
|
912
|
-
@kwarg outmask: Bit-or'ed combination of L{Caps} values specifying
|
|
913
|
-
|
|
910
|
+
@arg s12: The distance along this rhumb line from its origin to the point
|
|
911
|
+
(C{meters}), can be negative.
|
|
912
|
+
@kwarg outmask: Bit-or'ed combination of L{Caps} values specifying the
|
|
913
|
+
quantities to be returned.
|
|
914
914
|
|
|
915
|
-
@return: L{GDict} with 4 to 8 items C{azi12, a12, s12, S12, lat2,
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
915
|
+
@return: L{GDict} with 4 to 8 items C{azi12, a12, s12, S12, lat2, lat1,
|
|
916
|
+
lon2, lon1} with latitude C{lat2} and longitude C{lon2} of the
|
|
917
|
+
point in C{degrees}, the rhumb angle C{a12} in C{degrees} from
|
|
918
|
+
the start point of and the area C{S12} under this rhumb line
|
|
919
|
+
in C{meter} I{squared}.
|
|
920
920
|
|
|
921
|
-
@raise ImportError: Package C{numpy} not found or not installed,
|
|
922
|
-
only
|
|
923
|
-
|
|
921
|
+
@raise ImportError: Package C{numpy} not found or not installed, required
|
|
922
|
+
only for L{RhumbLineAux} area C{S12} when C{B{exact}
|
|
923
|
+
is True}.
|
|
924
924
|
|
|
925
|
-
@note: If B{C{s12}} is large enough that the rhumb line crosses a
|
|
926
|
-
|
|
927
|
-
|
|
925
|
+
@note: If B{C{s12}} is large enough that the rhumb line crosses a pole, the
|
|
926
|
+
longitude of the second point is indeterminate and C{NAN} is returned
|
|
927
|
+
for C{lon2} and area C{S12}.
|
|
928
928
|
|
|
929
|
-
If the first point is a pole, the cosine of its latitude is
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
carried out in finite terms.
|
|
929
|
+
If the first point is a pole, the cosine of its latitude is taken to
|
|
930
|
+
be C{sqrt(L{EPS})}. This position is extremely close to the actual
|
|
931
|
+
pole and allows the calculation to be carried out in finite terms.
|
|
933
932
|
'''
|
|
934
933
|
return self._Position(self.m2degrees(s12), s12, outmask)
|
|
935
934
|
|
pygeodesy/rhumb/ekx.py
CHANGED
|
@@ -43,7 +43,7 @@ from pygeodesy.utily import atan1, sincos2_
|
|
|
43
43
|
from math import asinh, atan, cos, cosh, radians, sin, sinh, sqrt, tan
|
|
44
44
|
|
|
45
45
|
__all__ = _ALL_LAZY.rhumb_ekx
|
|
46
|
-
__version__ = '24.
|
|
46
|
+
__version__ = '24.06.11'
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class Rhumb(RhumbBase):
|
|
@@ -61,13 +61,12 @@ class Rhumb(RhumbBase):
|
|
|
61
61
|
@kwarg a_earth: This rhumb's earth model (L{Datum}, L{Ellipsoid},
|
|
62
62
|
L{Ellipsoid2}, L{a_f2Tuple}, 2-tuple C{(a, f)}) or
|
|
63
63
|
the (equatorial) radius (C{meter}, conventionally).
|
|
64
|
-
@kwarg f: The ellipsoid's flattening (C{scalar}),
|
|
65
|
-
C{scalar}, ignored otherwise.
|
|
64
|
+
@kwarg f: The ellipsoid's flattening (C{scalar}), required if B{C{a_earth}}
|
|
65
|
+
is C{scalar}, ignored otherwise.
|
|
66
66
|
@kwarg exact: If C{True}, use an addition theorem for elliptic integrals
|
|
67
67
|
to compute I{Divided differences}, otherwise use the I{Krüger}
|
|
68
68
|
series expansion (C{bool} or C{None}), see also properties
|
|
69
69
|
C{exact} and C{TMorder}.
|
|
70
|
-
@kwarg name: Optional name (C{str}).
|
|
71
70
|
@kwarg RA_TMorder_name: Optional C{B{name}=NN} (C{str}) and optional keyword
|
|
72
71
|
arguments B{C{RAorder}=6} and B{C{TMorder}=6} to set the respective
|
|
73
72
|
C{order}, see properties C{RAorder} and C{TMorder}.
|
pygeodesy/rhumb/solve.py
CHANGED
|
@@ -21,7 +21,7 @@ from pygeodesy.solveBase import _SolveBase, _SolveLineBase
|
|
|
21
21
|
from pygeodesy.utily import _unrollon, _Wrap, wrap360
|
|
22
22
|
|
|
23
23
|
__all__ = _ALL_LAZY.rhumb_solve
|
|
24
|
-
__version__ = '24.
|
|
24
|
+
__version__ = '24.06.04'
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class _RhumbSolveBase(_SolveBase):
|
|
@@ -37,9 +37,9 @@ class _RhumbSolveBase(_SolveBase):
|
|
|
37
37
|
def _cmdBasic(self):
|
|
38
38
|
'''(INTERNAL) Get the basic C{RhumbSolve} cmd (C{tuple}).
|
|
39
39
|
'''
|
|
40
|
-
return (self.RhumbSolve,) + self._e_option
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
return (self.RhumbSolve,) + (self._e_option +
|
|
41
|
+
self._p_option +
|
|
42
|
+
self._s_option)
|
|
43
43
|
|
|
44
44
|
@Property
|
|
45
45
|
def RhumbSolve(self):
|
|
@@ -423,59 +423,6 @@ if __name__ == '__main__':
|
|
|
423
423
|
# p = rlS.ArcPosition(49.475527)
|
|
424
424
|
# printf('ArcPosition: %s %r', p == r, p)
|
|
425
425
|
|
|
426
|
-
# % python3 -m pygeodesy.rhumb.solve
|
|
427
|
-
|
|
428
|
-
# version: /opt/local/bin/RhumbSolve: GeographicLib version 1.51
|
|
429
|
-
#
|
|
430
|
-
# Direct: GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
431
|
-
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
432
|
-
#
|
|
433
|
-
# Inverse: GDict(S12=37395209100030.367188, a12=51.929543, azi12=77.76839, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, s12=5771083.383328)
|
|
434
|
-
# Inverse1: 51.92954250756195
|
|
435
|
-
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
436
|
-
#
|
|
437
|
-
# Inverse: GDict(S12=-63760642939072.492188, a12=115.02062, azi12=-92.388888, lat1=40.6, lat2=35.8, lon1=-73.8, lon2=140.3, s12=12782581.067684)
|
|
438
|
-
# Inverse1: 115.02061966879258
|
|
439
|
-
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
440
|
-
#
|
|
441
|
-
# Position: True GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
# % python3 -m pygeodesy.rhumb.solve --verbose
|
|
445
|
-
|
|
446
|
-
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve --version (invoke)
|
|
447
|
-
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve: GeographicLib version 1.51 (0)
|
|
448
|
-
# version: /opt/local/bin/RhumbSolve: GeographicLib version 1.51
|
|
449
|
-
# RhumbSolve 'Test' 2: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
|
|
450
|
-
# RhumbSolve 'Test' 2: lat2=71.688899882813047, lon2=0.255519824423445, S12=44095641862956.148 (0)
|
|
451
|
-
|
|
452
|
-
# Direct: GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
453
|
-
# RhumbSolve 'Test' 3: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
|
|
454
|
-
# RhumbSolve 'Test' 3: lat2=71.688899882813047, lon2=0.255519824423445, S12=44095641862956.148 (0)
|
|
455
|
-
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
456
|
-
# RhumbSolve 'Test' 4: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
|
|
457
|
-
# RhumbSolve 'Test' 4: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
458
|
-
|
|
459
|
-
# Inverse: GDict(S12=37395209100030.367188, a12=51.929543, azi12=77.76839, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, s12=5771083.383328)
|
|
460
|
-
# RhumbSolve 'Test' 5: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
|
|
461
|
-
# RhumbSolve 'Test' 5: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
462
|
-
# Inverse1: 51.92954250756195
|
|
463
|
-
# RhumbSolve 'Test' 6: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
|
|
464
|
-
# RhumbSolve 'Test' 6: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
465
|
-
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
466
|
-
# RhumbSolve 'Test' 7: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse)
|
|
467
|
-
# RhumbSolve 'Test' 7: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
468
|
-
|
|
469
|
-
# Inverse: GDict(S12=-63760642939072.492188, a12=115.02062, azi12=-92.388888, lat1=40.6, lat2=35.8, lon1=-73.8, lon2=140.3, s12=12782581.067684)
|
|
470
|
-
# RhumbSolve 'Test' 8: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse1)
|
|
471
|
-
# RhumbSolve 'Test' 8: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
472
|
-
# Inverse1: 115.02061966879258
|
|
473
|
-
# RhumbSolve 'Test' 9: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse3)
|
|
474
|
-
# RhumbSolve 'Test' 9: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
475
|
-
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
476
|
-
|
|
477
|
-
# Position: True GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
478
|
-
|
|
479
426
|
|
|
480
427
|
# % python3 -m pygeodesy.rhumb.solve
|
|
481
428
|
|
|
@@ -485,11 +432,11 @@ if __name__ == '__main__':
|
|
|
485
432
|
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
486
433
|
|
|
487
434
|
# Inverse: GDict(a12=51.929543, azi12=77.76839, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, s12=5771083.383328, S12=37395209100030.390625)
|
|
488
|
-
# Inverse1: 51.
|
|
435
|
+
# Inverse1: 51.929542507561905
|
|
489
436
|
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
490
437
|
|
|
491
438
|
# Inverse: GDict(a12=115.02062, azi12=-92.388888, lat1=40.6, lat2=35.8, lon1=-73.8, lon2=140.3, s12=12782581.067684, S12=-63760642939072.5)
|
|
492
|
-
# Inverse1: 115.
|
|
439
|
+
# Inverse1: 115.02061966879248
|
|
493
440
|
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
494
441
|
|
|
495
442
|
# Position: True GDict(azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0, S12=44095641862956.109375)
|
|
@@ -513,7 +460,7 @@ if __name__ == '__main__':
|
|
|
513
460
|
# Inverse: GDict(a12=51.929543, azi12=77.76839, lat1=40.6, lat2=51.6, lon1=-73.8, lon2=-0.5, s12=5771083.383328, S12=37395209100030.390625)
|
|
514
461
|
# RhumbSolve 'Test' 5: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
|
|
515
462
|
# RhumbSolve 'Test' 5: azi12=77.768389710255661, s12=5771083.383328028, S12=37395209100030.391 (0)
|
|
516
|
-
# Inverse1: 51.
|
|
463
|
+
# Inverse1: 51.929542507561905
|
|
517
464
|
# RhumbSolve 'Test' 6: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
|
|
518
465
|
# RhumbSolve 'Test' 6: azi12=77.768389710255661, s12=5771083.383328028, S12=37395209100030.391 (0)
|
|
519
466
|
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
@@ -523,7 +470,7 @@ if __name__ == '__main__':
|
|
|
523
470
|
# Inverse: GDict(a12=115.02062, azi12=-92.388888, lat1=40.6, lat2=35.8, lon1=-73.8, lon2=140.3, s12=12782581.067684, S12=-63760642939072.5)
|
|
524
471
|
# RhumbSolve 'Test' 8: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse1)
|
|
525
472
|
# RhumbSolve 'Test' 8: azi12=-92.388887981699654, s12=12782581.0676841699, S12=-63760642939072.5 (0)
|
|
526
|
-
# Inverse1: 115.
|
|
473
|
+
# Inverse1: 115.02061966879248
|
|
527
474
|
# RhumbSolve 'Test' 9: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse3)
|
|
528
475
|
# RhumbSolve 'Test' 9: azi12=-92.388887981699654, s12=12782581.0676841699, S12=-63760642939072.5 (0)
|
|
529
476
|
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
pygeodesy/solveBase.py
CHANGED
|
@@ -13,7 +13,7 @@ from pygeodesy.internals import _enquote, printf
|
|
|
13
13
|
from pygeodesy.interns import NN, _0_, _BACKSLASH_, _COMMASPACE_, \
|
|
14
14
|
_EQUAL_, _Error_, _SPACE_, _UNUSED_
|
|
15
15
|
from pygeodesy.karney import Caps, _CapsBase, GDict
|
|
16
|
-
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY,
|
|
16
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _sys_version_info2
|
|
17
17
|
from pygeodesy.named import callername, _name2__, notOverloaded
|
|
18
18
|
from pygeodesy.props import Property, Property_RO, property_RO, _update_all
|
|
19
19
|
from pygeodesy.streprs import Fmt, fstr, fstrzs, pairs, strs
|
|
@@ -23,34 +23,37 @@ from pygeodesy.utily import unroll180, wrap360 # PYCHOK shared
|
|
|
23
23
|
from subprocess import PIPE as _PIPE, Popen as _Popen, STDOUT as _STDOUT
|
|
24
24
|
|
|
25
25
|
__all__ = _ALL_LAZY.solveBase
|
|
26
|
-
__version__ = '24.05
|
|
26
|
+
__version__ = '24.06.05'
|
|
27
27
|
|
|
28
|
-
_ERROR_
|
|
29
|
-
|
|
28
|
+
_ERROR_ = 'ERROR'
|
|
29
|
+
_Popen_kwds = dict(creationflags=0,
|
|
30
|
+
# executable=sys.executable, shell=True,
|
|
31
|
+
stdin=_PIPE, stdout=_PIPE, stderr=_STDOUT)
|
|
32
|
+
if _sys_version_info2 > (3, 6):
|
|
33
|
+
_Popen_kwds.update(text=True)
|
|
34
|
+
del _PIPE, _STDOUT, _sys_version_info2 # _ALL_LAZY
|
|
30
35
|
|
|
31
36
|
|
|
32
37
|
def _cmd_stdin_(cmd, stdin): # PYCHOK no cover
|
|
33
38
|
'''(INTERNAL) Cmd line, stdin and caller as sC{str}.
|
|
34
39
|
'''
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
if stdin is not None:
|
|
41
|
+
cmd += _BACKSLASH_, str(stdin)
|
|
42
|
+
cmd += Fmt.PAREN(callername(up=3)),
|
|
43
|
+
return _SPACE_.join(cmd)
|
|
38
44
|
|
|
39
45
|
|
|
40
|
-
def _popen2(cmd, stdin=None): # in .mgrs,
|
|
46
|
+
def _popen2(cmd, stdin=None): # in .mgrs, test.bases, .testMgrs
|
|
41
47
|
'''(INTERNAL) Invoke C{B{cmd} tuple} and return C{exitcode}
|
|
42
48
|
and all output to C{stdout/-err}.
|
|
43
49
|
'''
|
|
44
|
-
p = _Popen(cmd,
|
|
45
|
-
|
|
46
|
-
stdin=_PIPE, stdout=_PIPE, stderr=_STDOUT,
|
|
47
|
-
**_text_True) # PYCHOK kwArgs
|
|
48
|
-
r = p.communicate(stdin)[0]
|
|
50
|
+
p = _Popen(cmd, **_Popen_kwds) # PYCHOK kwArgs
|
|
51
|
+
r = p.communicate(stdin)[0]
|
|
49
52
|
return p.returncode, ub2str(r).strip()
|
|
50
53
|
|
|
51
54
|
|
|
52
|
-
class
|
|
53
|
-
'''(NTERNAL) Base class for C{
|
|
55
|
+
class _SolveCapsBase(_CapsBase):
|
|
56
|
+
'''(NTERNAL) Base class for C{_SolveBase} and C{_LineSolveBase}.
|
|
54
57
|
'''
|
|
55
58
|
_Error = None
|
|
56
59
|
_Exact = True
|
|
@@ -131,7 +134,7 @@ class _SolveLineSolveBase(_CapsBase):
|
|
|
131
134
|
|
|
132
135
|
@note: The C{Solve} return code is in property L{status}.
|
|
133
136
|
'''
|
|
134
|
-
c = (self._Solve_path,) + map2(str, options)
|
|
137
|
+
c = (self._Solve_path,) + map2(str, options) # map2(_enquote, options)
|
|
135
138
|
i = _xkwds_get1(stdin, stdin=None)
|
|
136
139
|
r = self._invoke(c, stdin=i)
|
|
137
140
|
s = self.status
|
|
@@ -270,7 +273,7 @@ class _SolveLineSolveBase(_CapsBase):
|
|
|
270
273
|
return self.invoke('--version')
|
|
271
274
|
|
|
272
275
|
|
|
273
|
-
class _SolveBase(
|
|
276
|
+
class _SolveBase(_SolveCapsBase):
|
|
274
277
|
'''(NTERNAL) Base class for C{_GeodesicSolveBase} and C{_RhumbSolveBase}.
|
|
275
278
|
'''
|
|
276
279
|
_datum = _WGS84
|
|
@@ -387,7 +390,7 @@ class _SolveBase(_SolveLineSolveBase):
|
|
|
387
390
|
return sep.join(pairs(d, prec=prec))
|
|
388
391
|
|
|
389
392
|
|
|
390
|
-
class _SolveLineBase(
|
|
393
|
+
class _SolveLineBase(_SolveCapsBase):
|
|
391
394
|
'''(NTERNAL) Base class for C{GeodesicLineSolve} and C{RhumbLineSolve}.
|
|
392
395
|
'''
|
|
393
396
|
# _caps = 0
|
|
@@ -448,7 +451,7 @@ class _SolveLineBase(_SolveLineSolveBase):
|
|
|
448
451
|
return sep.join(pairs(d, prec=prec))
|
|
449
452
|
|
|
450
453
|
|
|
451
|
-
__all__ += _ALL_DOCS(_SolveBase, _SolveLineBase,
|
|
454
|
+
__all__ += _ALL_DOCS(_SolveBase, _SolveLineBase, _SolveCapsBase)
|
|
452
455
|
|
|
453
456
|
# **) MIT License
|
|
454
457
|
#
|
pygeodesy/sphericalBase.py
CHANGED
|
@@ -19,7 +19,7 @@ from pygeodesy.constants import EPS, EPS0, PI, PI2, PI_2, R_M, \
|
|
|
19
19
|
_over, isnear0, isnon0
|
|
20
20
|
from pygeodesy.datums import Datums, _earth_ellipsoid, _spherical_datum
|
|
21
21
|
from pygeodesy.errors import IntersectionError, _ValueError, \
|
|
22
|
-
_xattr, _xError
|
|
22
|
+
_xattr, _xattrs, _xError
|
|
23
23
|
from pygeodesy.fmath import favg, fdot, hypot, sqrt_a
|
|
24
24
|
from pygeodesy.interns import _COMMA_, _concentric_, _datum_, _distant_, \
|
|
25
25
|
_exceed_PI_radians_, _name_, _near_, \
|
|
@@ -27,10 +27,10 @@ from pygeodesy.interns import _COMMA_, _concentric_, _datum_, _distant_, \
|
|
|
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
|
-
from pygeodesy.nvectorBase import NvectorBase, Fmt
|
|
30
|
+
from pygeodesy.nvectorBase import NvectorBase, Fmt
|
|
31
31
|
from pygeodesy.props import deprecated_method, property_doc_, property_RO, \
|
|
32
32
|
_update_all
|
|
33
|
-
# from pygeodesy.streprs import Fmt
|
|
33
|
+
# from pygeodesy.streprs import Fmt # from .nvectorBase
|
|
34
34
|
from pygeodesy.units import Bearing, Bearing_, _isRadius, Radians_, Radius, \
|
|
35
35
|
Radius_, Scalar_, _100km
|
|
36
36
|
from pygeodesy.utily import acos1, asin1, atan2b, atan2d, degrees90, \
|
|
@@ -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__ = '24.
|
|
43
|
+
__version__ = '24.06.12'
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class CartesianSphericalBase(CartesianBase):
|
|
@@ -380,7 +380,8 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
380
380
|
'''DEPRECATED, use method C{.rhumbAzimuthTo}.'''
|
|
381
381
|
return self.rhumbAzimuthTo(other, b360=True) # [0..360)
|
|
382
382
|
|
|
383
|
-
def rhumbDestination(self, distance, azimuth, radius=R_M, height=None,
|
|
383
|
+
def rhumbDestination(self, distance, azimuth, radius=R_M, height=None,
|
|
384
|
+
exact=False, **name):
|
|
384
385
|
'''Return the destination point having travelled the given distance from
|
|
385
386
|
this point along a rhumb line (loxodrome) of the given azimuth.
|
|
386
387
|
|
|
@@ -393,6 +394,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
393
394
|
@kwarg height: Optional height, overriding the default height (C{meter}.
|
|
394
395
|
@kwarg exact: If C{True}, use I{Elliptic, Krüger} L{Rhumb} (C{bool}),
|
|
395
396
|
default C{False} for backward compatibility.
|
|
397
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
396
398
|
|
|
397
399
|
@return: The destination point (spherical C{LatLon}).
|
|
398
400
|
|
|
@@ -401,7 +403,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
401
403
|
'''
|
|
402
404
|
if exact: # use series, always
|
|
403
405
|
r = LatLonBase.rhumbDestination(self, distance, azimuth, exact=False, # Krüger
|
|
404
|
-
radius=radius, height=height)
|
|
406
|
+
radius=radius, height=height, **name)
|
|
405
407
|
else: # radius=None from .rhumbMidpointTo
|
|
406
408
|
if radius in (None, self._radius):
|
|
407
409
|
d, r = self.datum, radius
|
|
@@ -425,7 +427,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
425
427
|
b2 = b1 if isnear0(q) else (b1 + r * sb / q)
|
|
426
428
|
|
|
427
429
|
h = self._heigHt(height)
|
|
428
|
-
r = self.classof(degrees90(a2), degrees180(b2), datum=d, height=h)
|
|
430
|
+
r = self.classof(degrees90(a2), degrees180(b2), datum=d, height=h, **name)
|
|
429
431
|
return r
|
|
430
432
|
|
|
431
433
|
def rhumbDistanceTo(self, other, radius=R_M, exact=False, wrap=False):
|
|
@@ -441,8 +443,8 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
441
443
|
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll the
|
|
442
444
|
B{C{other}} point (C{bool}).
|
|
443
445
|
|
|
444
|
-
@return: Distance (C{meter}, the same units as B{C{radius}}
|
|
445
|
-
|
|
446
|
+
@return: Distance (C{meter}, the same units as B{C{radius}} or
|
|
447
|
+
C{radians} if C{B{radius} is None}).
|
|
446
448
|
|
|
447
449
|
@raise TypeError: The B{C{other}} point is incompatible.
|
|
448
450
|
|
|
@@ -499,7 +501,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
499
501
|
height=height, wrap=wrap)
|
|
500
502
|
|
|
501
503
|
def rhumbMidpointTo(self, other, height=None, radius=R_M, exact=False,
|
|
502
|
-
fraction=_0_5,
|
|
504
|
+
fraction=_0_5, **wrap_name):
|
|
503
505
|
'''Return the (loxodromic) midpoint on the rhumb line between
|
|
504
506
|
this and an other point.
|
|
505
507
|
|
|
@@ -511,8 +513,9 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
511
513
|
default C{False} for backward compatibility.
|
|
512
514
|
@kwarg fraction: Midpoint location from this point (C{scalar}), may
|
|
513
515
|
be negative if C{B{exact}=True}.
|
|
514
|
-
@kwarg
|
|
515
|
-
|
|
516
|
+
@kwarg wrap_name: Optional C{B{name}=NN} (C{str}) and optional keyword
|
|
517
|
+
argument C{B{wrap}=False}, if C{True}, wrap or I{normalize}
|
|
518
|
+
and unroll the B{C{other}} point (C{bool}).
|
|
516
519
|
|
|
517
520
|
@return: The (mid)point at the given B{C{fraction}} along the rhumb
|
|
518
521
|
line (spherical C{LatLon}).
|
|
@@ -524,18 +527,21 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
524
527
|
if exact: # use series, always
|
|
525
528
|
r = LatLonBase.rhumbMidpointTo(self, other, exact=False, # Krüger
|
|
526
529
|
radius=radius, height=height,
|
|
527
|
-
fraction=fraction,
|
|
530
|
+
fraction=fraction, **wrap_name)
|
|
528
531
|
elif fraction is not _0_5:
|
|
529
532
|
f = Scalar_(fraction=fraction) # low=_0_0
|
|
530
|
-
|
|
533
|
+
w, n = self._wrap_name2(**wrap_name)
|
|
534
|
+
r, db, dp = self._rhumbs3(other, w, r=True) # radians
|
|
531
535
|
z = atan2b(db, dp)
|
|
532
536
|
h = self._havg(other, f=f, h=height)
|
|
533
|
-
r = self.rhumbDestination(r * f, z, radius=None, height=h)
|
|
537
|
+
r = self.rhumbDestination(r * f, z, radius=None, height=h, name=n)
|
|
534
538
|
|
|
535
539
|
else: # for backward compatibility, unwrapped
|
|
540
|
+
_, n = self._wrap_name2(**wrap_name)
|
|
536
541
|
# see <https://MathForum.org/library/drmath/view/51822.html>
|
|
537
542
|
a1, b1 = self.philam
|
|
538
543
|
a2, b2 = self.others(other).philam
|
|
544
|
+
_, n = self._wrap_name2(**wrap_name)
|
|
539
545
|
|
|
540
546
|
if fabs(b2 - b1) > PI:
|
|
541
547
|
b1 += PI2 # crossing anti-meridian
|
|
@@ -557,7 +563,7 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
557
563
|
d = self.datum if radius in (None, self._radius) else \
|
|
558
564
|
_spherical_datum(radius, name=self.name, raiser=_radius_)
|
|
559
565
|
h = self._havg(other, h=height)
|
|
560
|
-
r = self.classof(degrees90(a3), degrees180(b3), datum=d, height=h)
|
|
566
|
+
r = self.classof(degrees90(a3), degrees180(b3), datum=d, height=h, name=n)
|
|
561
567
|
return r
|
|
562
568
|
|
|
563
569
|
@property_RO
|
|
@@ -570,12 +576,11 @@ class LatLonSphericalBase(LatLonBase):
|
|
|
570
576
|
'''Convert this point to C{Nvector} components, I{including
|
|
571
577
|
height}.
|
|
572
578
|
|
|
573
|
-
@kwarg Nvector_kwds: Optional, additional B{C{Nvector}}
|
|
574
|
-
|
|
575
|
-
C{B{Nvector} is None}.
|
|
579
|
+
@kwarg Nvector_kwds: Optional, additional B{C{Nvector}} keyword
|
|
580
|
+
arguments, ignored if C{B{Nvector} is None}.
|
|
576
581
|
|
|
577
|
-
@return: An B{C{Nvector}} or a L{Vector4Tuple}C{(x, y, z, h)}
|
|
578
|
-
|
|
582
|
+
@return: An B{C{Nvector}} or a L{Vector4Tuple}C{(x, y, z, h)} if
|
|
583
|
+
B{C{Nvector} is None}.
|
|
579
584
|
|
|
580
585
|
@raise TypeError: Invalid B{C{Nvector}} or B{C{Nvector_kwds}}.
|
|
581
586
|
'''
|