pygeodesy 24.3.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.3.24.dist-info/METADATA +272 -0
- PyGeodesy-24.3.24.dist-info/RECORD +115 -0
- PyGeodesy-24.3.24.dist-info/WHEEL +6 -0
- PyGeodesy-24.3.24.dist-info/top_level.txt +1 -0
- pygeodesy/LICENSE +21 -0
- pygeodesy/__init__.py +615 -0
- pygeodesy/__main__.py +103 -0
- pygeodesy/albers.py +867 -0
- pygeodesy/auxilats/_CX_4.py +218 -0
- pygeodesy/auxilats/_CX_6.py +314 -0
- pygeodesy/auxilats/_CX_8.py +475 -0
- pygeodesy/auxilats/__init__.py +54 -0
- pygeodesy/auxilats/__main__.py +86 -0
- pygeodesy/auxilats/auxAngle.py +548 -0
- pygeodesy/auxilats/auxDLat.py +302 -0
- pygeodesy/auxilats/auxDST.py +296 -0
- pygeodesy/auxilats/auxLat.py +848 -0
- pygeodesy/auxilats/auxily.py +272 -0
- pygeodesy/azimuthal.py +1150 -0
- pygeodesy/basics.py +892 -0
- pygeodesy/booleans.py +2031 -0
- pygeodesy/cartesianBase.py +1062 -0
- pygeodesy/clipy.py +704 -0
- pygeodesy/constants.py +516 -0
- pygeodesy/css.py +660 -0
- pygeodesy/datums.py +752 -0
- pygeodesy/deprecated/__init__.py +61 -0
- pygeodesy/deprecated/bases.py +40 -0
- pygeodesy/deprecated/classes.py +262 -0
- pygeodesy/deprecated/consterns.py +54 -0
- pygeodesy/deprecated/datum.py +40 -0
- pygeodesy/deprecated/functions.py +375 -0
- pygeodesy/deprecated/nvector.py +48 -0
- pygeodesy/deprecated/rhumbBase.py +32 -0
- pygeodesy/deprecated/rhumbaux.py +33 -0
- pygeodesy/deprecated/rhumbsolve.py +33 -0
- pygeodesy/deprecated/rhumbx.py +33 -0
- pygeodesy/dms.py +986 -0
- pygeodesy/ecef.py +1348 -0
- pygeodesy/elevations.py +279 -0
- pygeodesy/ellipsoidalBase.py +1224 -0
- pygeodesy/ellipsoidalBaseDI.py +913 -0
- pygeodesy/ellipsoidalExact.py +343 -0
- pygeodesy/ellipsoidalGeodSolve.py +343 -0
- pygeodesy/ellipsoidalKarney.py +403 -0
- pygeodesy/ellipsoidalNvector.py +685 -0
- pygeodesy/ellipsoidalVincenty.py +590 -0
- pygeodesy/ellipsoids.py +2476 -0
- pygeodesy/elliptic.py +1198 -0
- pygeodesy/epsg.py +243 -0
- pygeodesy/errors.py +804 -0
- pygeodesy/etm.py +1190 -0
- pygeodesy/fmath.py +1013 -0
- pygeodesy/formy.py +1818 -0
- pygeodesy/frechet.py +865 -0
- pygeodesy/fstats.py +760 -0
- pygeodesy/fsums.py +1898 -0
- pygeodesy/gars.py +358 -0
- pygeodesy/geodesicw.py +581 -0
- pygeodesy/geodesicx/_C4_24.py +1699 -0
- pygeodesy/geodesicx/_C4_27.py +2395 -0
- pygeodesy/geodesicx/_C4_30.py +3301 -0
- pygeodesy/geodesicx/__init__.py +48 -0
- pygeodesy/geodesicx/__main__.py +91 -0
- pygeodesy/geodesicx/gx.py +1382 -0
- pygeodesy/geodesicx/gxarea.py +535 -0
- pygeodesy/geodesicx/gxbases.py +154 -0
- pygeodesy/geodesicx/gxline.py +669 -0
- pygeodesy/geodsolve.py +426 -0
- pygeodesy/geohash.py +914 -0
- pygeodesy/geoids.py +1884 -0
- pygeodesy/hausdorff.py +892 -0
- pygeodesy/heights.py +1155 -0
- pygeodesy/interns.py +687 -0
- pygeodesy/iters.py +545 -0
- pygeodesy/karney.py +919 -0
- pygeodesy/ktm.py +633 -0
- pygeodesy/latlonBase.py +1766 -0
- pygeodesy/lazily.py +960 -0
- pygeodesy/lcc.py +684 -0
- pygeodesy/ltp.py +1107 -0
- pygeodesy/ltpTuples.py +1563 -0
- pygeodesy/mgrs.py +721 -0
- pygeodesy/named.py +1324 -0
- pygeodesy/namedTuples.py +683 -0
- pygeodesy/nvectorBase.py +695 -0
- pygeodesy/osgr.py +781 -0
- pygeodesy/points.py +1686 -0
- pygeodesy/props.py +628 -0
- pygeodesy/resections.py +1048 -0
- pygeodesy/rhumb/__init__.py +46 -0
- pygeodesy/rhumb/aux_.py +397 -0
- pygeodesy/rhumb/bases.py +1148 -0
- pygeodesy/rhumb/ekx.py +563 -0
- pygeodesy/rhumb/solve.py +572 -0
- pygeodesy/simplify.py +647 -0
- pygeodesy/solveBase.py +472 -0
- pygeodesy/sphericalBase.py +724 -0
- pygeodesy/sphericalNvector.py +1264 -0
- pygeodesy/sphericalTrigonometry.py +1447 -0
- pygeodesy/streprs.py +627 -0
- pygeodesy/trf.py +2079 -0
- pygeodesy/triaxials.py +1484 -0
- pygeodesy/units.py +969 -0
- pygeodesy/unitsBase.py +349 -0
- pygeodesy/ups.py +538 -0
- pygeodesy/utily.py +1231 -0
- pygeodesy/utm.py +762 -0
- pygeodesy/utmups.py +318 -0
- pygeodesy/utmupsBase.py +517 -0
- pygeodesy/vector2d.py +785 -0
- pygeodesy/vector3d.py +968 -0
- pygeodesy/vector3dBase.py +1049 -0
- pygeodesy/webmercator.py +383 -0
- pygeodesy/wgrs.py +439 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''Package of lazily imported C{rhumb} modules L{rhumb.aux_}, L{rhumb.ekx} and L{rhumb.solve}.
|
|
5
|
+
|
|
6
|
+
@note: C{S12} area calculations in classes L{RhumbAux} and L{RhumbLineAux} depend on class L{AuxDST}
|
|
7
|
+
which requires U{numpy<https://PyPI.org/project/numpy>} to be installed, version 1.16 or newer.
|
|
8
|
+
'''
|
|
9
|
+
from pygeodesy.lazily import _ALL_LAZY, _ALL_OTHER, _lazy_import_as, _unLazy0
|
|
10
|
+
|
|
11
|
+
__all__ = _ALL_LAZY.rhumb
|
|
12
|
+
__version__ = '23.12.29'
|
|
13
|
+
|
|
14
|
+
if _unLazy0: # or _isfrozen
|
|
15
|
+
from pygeodesy.rhumb.aux_ import RhumbAux, RhumbLineAux
|
|
16
|
+
from pygeodesy.rhumb.ekx import Rhumb, RhumbLine
|
|
17
|
+
from pygeodesy.rhumb.solve import RhumbSolve, RhumbLineSolve, RhumbSolve7Tuple
|
|
18
|
+
|
|
19
|
+
__all__ += _ALL_OTHER(RhumbAux, RhumbLineAux, Rhumb, RhumbLine,
|
|
20
|
+
RhumbSolve, RhumbLineSolve, RhumbSolve7Tuple)
|
|
21
|
+
assert _ALL_LAZY.rhumb_aux_ + _ALL_LAZY.rhumb_ekx + _ALL_LAZY.rhumb_solve == __all__
|
|
22
|
+
|
|
23
|
+
else: # lazily import modules and exported attrs
|
|
24
|
+
__getattr__ = _lazy_import_as(__name__)
|
|
25
|
+
|
|
26
|
+
# **) MIT License
|
|
27
|
+
#
|
|
28
|
+
# Copyright (C) 2018-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
29
|
+
#
|
|
30
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
31
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
32
|
+
# to deal in the Software without restriction, including without limitation
|
|
33
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
34
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
35
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
36
|
+
#
|
|
37
|
+
# The above copyright notice and this permission notice shall be included
|
|
38
|
+
# in all copies or substantial portions of the Software.
|
|
39
|
+
#
|
|
40
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
41
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
42
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
43
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
44
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
45
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
46
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
pygeodesy/rhumb/aux_.py
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''A pure Python version of I{Karney}'s I{Auxiliary Latitudes}, C++ classes U{Rhumb
|
|
5
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1Rhumb.html>} and U{RhumbLine
|
|
6
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1RhumbLine.html>} from
|
|
7
|
+
I{GeographicLib version 2.2+} renamed to L{RhumbAux} respectively L{RhumbLineAux}.
|
|
8
|
+
|
|
9
|
+
Class L{RhumbLineAux} has been enhanced with methods C{Intersecant2}, C{Intersection} and C{PlumbTo}
|
|
10
|
+
to iteratively find the intersection of a rhumb line and a circle or an other rhumb line, respectively
|
|
11
|
+
a perpendicular geodesic or other rhumb line.
|
|
12
|
+
|
|
13
|
+
For more details, see the U{GeographicLib<https://GeographicLib.SourceForge.io/C++/doc/index.html>} I{2.2}
|
|
14
|
+
documentation, especially the U{Class List<https://GeographicLib.SourceForge.io/C++/doc/annotated.html>},
|
|
15
|
+
the background information on U{Rhumb lines<https://GeographicLib.SourceForge.io/C++/doc/rhumb.html>},
|
|
16
|
+
utility U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>} and U{Online rhumb
|
|
17
|
+
line calculations<https://GeographicLib.SourceForge.io/cgi-bin/RhumbSolve>}.
|
|
18
|
+
|
|
19
|
+
Copyright (C) U{Charles Karney<mailto:Karney@Alum.MIT.edu>} (2022-2023) and licensed under the MIT/X11
|
|
20
|
+
License. For more information, see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
21
|
+
|
|
22
|
+
@note: C{S12} area calculations in classes L{RhumbAux} and L{RhumbLineAux} depend on class L{AuxDST} which
|
|
23
|
+
requires U{numpy<https://PyPI.org/project/numpy>} to be installed, version 1.16 or newer.
|
|
24
|
+
|
|
25
|
+
@note: Windows reserves file names U{AUX, COM[#], CON, LPT[#], NUL, PRN<https://learn.Microsoft.com/en-us/
|
|
26
|
+
windows/win32/fileio/naming-a-file#naming-conventions>} with and without extension.
|
|
27
|
+
'''
|
|
28
|
+
# make sure int/int division yields float quotient
|
|
29
|
+
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
30
|
+
|
|
31
|
+
from pygeodesy.auxilats.auxAngle import AuxMu, AuxPhi, hypot
|
|
32
|
+
from pygeodesy.auxilats.auxDLat import AuxDLat, _DClenshaw
|
|
33
|
+
# from pygeodesy.auxilats.auxDST import AuxDST # _MODS
|
|
34
|
+
from pygeodesy.auxilats.auxily import _Dlam, _Dp0Dpsi, _Ufloats
|
|
35
|
+
from pygeodesy.basics import copysign0, _reverange, _xkwds_get
|
|
36
|
+
from pygeodesy.constants import EPS_2, MANT_DIG, PI4, isinf, \
|
|
37
|
+
_0_0, _4_0, _720_0, _log2, _over
|
|
38
|
+
from pygeodesy.datums import _WGS84, NN
|
|
39
|
+
# from pygeodesy.errors import _xkwds_get # from .basics
|
|
40
|
+
from pygeodesy.karney import Caps, _polynomial
|
|
41
|
+
# from pygeodesy.fmath import hypot # from .auxilats.auxAngle
|
|
42
|
+
# from pygeodesy.interns import NN # from .datums
|
|
43
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
44
|
+
# from pygeodesy.props import Property_RO # from .rhumbBase
|
|
45
|
+
from pygeodesy.rhumb.bases import RhumbBase, RhumbLineBase, Property_RO
|
|
46
|
+
|
|
47
|
+
from math import ceil as _ceil, fabs, radians
|
|
48
|
+
|
|
49
|
+
__all__ = _ALL_LAZY.rhumb_aux_
|
|
50
|
+
__version__ = '23.12.09'
|
|
51
|
+
|
|
52
|
+
# DIGITS = (sizeof(real) * 8) bits
|
|
53
|
+
# = (ctypes.sizeof(ctypes.c_double(1.0)) * 8) bits
|
|
54
|
+
# For |n| <= 0.99, actual max for doubles is 2163. This scales
|
|
55
|
+
# as DIGITS and for long doubles (GEOGRAPHICLIB_PRECISION = 3,
|
|
56
|
+
# DIGITS = 64), this becomes 2163 * 64 / 53 = 2612. Round this
|
|
57
|
+
# up to 2^12 = 4096 and scale this by DIGITS//64 if DIGITS > 64.
|
|
58
|
+
#
|
|
59
|
+
# 64 = DIGITS for long double, 6 = 12 - _log2(64)
|
|
60
|
+
_Lbits = 1 << (int(_ceil(_log2(max(MANT_DIG, 64)))) + 6)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class RhumbAux(RhumbBase):
|
|
64
|
+
'''Class to solve the I{direct} and I{inverse rhumb} problems, based
|
|
65
|
+
on I{Auxiliary Latitudes} for accuracy near the poles.
|
|
66
|
+
|
|
67
|
+
@note: Package U{numpy<https://PyPI.org/project/numpy>} must be
|
|
68
|
+
installed, version 1.16 or later.
|
|
69
|
+
'''
|
|
70
|
+
|
|
71
|
+
def __init__(self, a_earth=_WGS84, f=None, exact=True, name=NN, **TMorder): # PYCHOK signature
|
|
72
|
+
'''New C{RhumbAux}.
|
|
73
|
+
|
|
74
|
+
@kwarg a_earth: This rhumb's earth model (L{Datum}, L{Ellipsoid},
|
|
75
|
+
L{Ellipsoid2}, L{a_f2Tuple}, 2-tuple C{(a, f)}) or
|
|
76
|
+
the (equatorial) radius (C{meter}, conventionally).
|
|
77
|
+
@kwarg f: The ellipsoid's flattening (C{scalar}), iff B{C{a_earth}} is
|
|
78
|
+
C{scalar}, ignored otherwise.
|
|
79
|
+
@kwarg exact: If C{True}, use the exact expressions for the I{Auxiliary
|
|
80
|
+
Latitudes}, otherwise use the I{Fourier} series expansion
|
|
81
|
+
(C{bool}), see also property C{exact}.
|
|
82
|
+
@kwarg name: Optional name (C{str}).
|
|
83
|
+
@kwarg TMorder: Optional keyword argument B{C{TMorder}}, see property
|
|
84
|
+
C{TMorder}.
|
|
85
|
+
|
|
86
|
+
@raise ImportError: Package C{numpy} not found or not installed, only
|
|
87
|
+
required for area C{S12} when C{B{exact} is True}.
|
|
88
|
+
|
|
89
|
+
@raise RhumbError: Invalid B{C{a_earth}}, B{C{f}} or B{C{TMorder}}.
|
|
90
|
+
'''
|
|
91
|
+
RhumbBase.__init__(self, a_earth, f, exact, name)
|
|
92
|
+
if TMorder:
|
|
93
|
+
self.Tmorder = _xkwds_get(TMorder, TMorder=RhumbBase._mTM)
|
|
94
|
+
|
|
95
|
+
def areaux(self, **exact):
|
|
96
|
+
'''Get this ellipsoid's B{C{exact}} surface area (C{meter} I{squared}).
|
|
97
|
+
|
|
98
|
+
@kwarg exact: Optional C{exact} (C{bool}), overriding this rhumb's
|
|
99
|
+
C{exact} setting, if C{True}, use the exact expression
|
|
100
|
+
for the authalic radius otherwise the I{Taylor} series.
|
|
101
|
+
|
|
102
|
+
@return: The (signed?) surface area (C{meter} I{squared}).
|
|
103
|
+
|
|
104
|
+
@raise AuxError: If C{B{exact}=False} and C{abs(flattening)} exceeds
|
|
105
|
+
property C{f_max}.
|
|
106
|
+
|
|
107
|
+
@note: The area of a polygon encircling a pole can be found by adding
|
|
108
|
+
C{areaux / 2} to the sum of C{S12} for each side of the polygon.
|
|
109
|
+
|
|
110
|
+
@see: U{The area of rhumb polygons<https://ArXiv.org/pdf/2303.03219.pdf>}
|
|
111
|
+
and method L{auxilats.AuxLat.AuthalicRadius2}.
|
|
112
|
+
'''
|
|
113
|
+
x = _xkwds_get(exact, exact=self.exact)
|
|
114
|
+
a = (self._c2 * _720_0) if bool(x) is self.exact else (
|
|
115
|
+
self._auxD.AuthalicRadius2(exact=x, f_max=self.f_max) * PI4)
|
|
116
|
+
return a
|
|
117
|
+
|
|
118
|
+
@Property_RO
|
|
119
|
+
def _auxD(self):
|
|
120
|
+
return AuxDLat(self.ellipsoid)
|
|
121
|
+
|
|
122
|
+
@Property_RO
|
|
123
|
+
def _c2(self): # radians makes _c2 a factor per degree
|
|
124
|
+
return radians(self._auxD.AuthalicRadius2(exact=self.exact, f_max=self.f_max))
|
|
125
|
+
|
|
126
|
+
def _DMu_DPsi(self, Phi1, Phi2, Chi1, Chi2):
|
|
127
|
+
xD = self._auxD
|
|
128
|
+
r = xD.DRectifying(Phi1, Phi2) if self.exact else \
|
|
129
|
+
xD.CRectifying(Chi1, Chi2)
|
|
130
|
+
if r:
|
|
131
|
+
r = _over(r, xD.DIsometric(Phi1, Phi2) if self.exact else
|
|
132
|
+
_Dlam(Chi1.tan, Chi2.tan)) # not Lambertian!
|
|
133
|
+
return r
|
|
134
|
+
|
|
135
|
+
def _Inverse4(self, lon12, r, outmask):
|
|
136
|
+
'''(INTERNAL) See method C{RhumbBase.Inverse}.
|
|
137
|
+
'''
|
|
138
|
+
psi1, Chi1, Phi1 = self._psiChiPhi3(r.lat1)
|
|
139
|
+
psi2, Chi2, Phi2 = self._psiChiPhi3(r.lat2)
|
|
140
|
+
psi12 = psi2 - psi1 # radians
|
|
141
|
+
lam12 = radians(lon12)
|
|
142
|
+
if (outmask & Caps.DISTANCE):
|
|
143
|
+
if isinf(psi1) or isinf(psi2): # PYCHOK no cover
|
|
144
|
+
s = fabs(Phi2.toMu(self).toRadians -
|
|
145
|
+
Phi1.toMu(self).toRadians)
|
|
146
|
+
else: # dmu/dpsi = dmu/dchi/dpsi/dchi
|
|
147
|
+
s = hypot(lam12, psi12)
|
|
148
|
+
if s:
|
|
149
|
+
s *= self._DMu_DPsi(Phi1, Phi2, Chi1, Chi2)
|
|
150
|
+
s *= self._rrm
|
|
151
|
+
a = _over(s, self._mpd)
|
|
152
|
+
r.set_(a12=copysign0(a, s), s12=s)
|
|
153
|
+
return lam12, psi12, Chi1, Chi2
|
|
154
|
+
|
|
155
|
+
def _latPhi2(self, mu):
|
|
156
|
+
Mu = AuxMu.fromDegrees(mu)
|
|
157
|
+
Phi = Mu.toPhi(self)
|
|
158
|
+
return Phi.toDegrees, Phi
|
|
159
|
+
|
|
160
|
+
@Property_RO
|
|
161
|
+
def _mpd(self): # meter per degree
|
|
162
|
+
return radians(self._rrm) # == self.ellipsoid._Lpd
|
|
163
|
+
|
|
164
|
+
def _psiChiPhi3(self, lat):
|
|
165
|
+
Phi = AuxPhi.fromDegrees(lat)
|
|
166
|
+
Chi = Phi.toChi(self)
|
|
167
|
+
psi = Chi.toLambertianRadians
|
|
168
|
+
return psi, Chi, Phi
|
|
169
|
+
|
|
170
|
+
@Property_RO
|
|
171
|
+
def _RA(self): # get the coefficients for area calculation
|
|
172
|
+
return tuple(_RAintegrate(self._auxD) if self.exact else
|
|
173
|
+
_RAseries(self._auxD))
|
|
174
|
+
|
|
175
|
+
# _RhumbLine = RhumbLineAux # see further below
|
|
176
|
+
|
|
177
|
+
@Property_RO
|
|
178
|
+
def _rrm(self):
|
|
179
|
+
return self._auxD.RectifyingRadius(exact=self.exact)
|
|
180
|
+
|
|
181
|
+
_mpr = _rrm # meter per radian, see _mpd
|
|
182
|
+
|
|
183
|
+
def _S12d(self, Chix, Chiy, lon12): # degrees
|
|
184
|
+
'''(INTERNAL) Compute the area C{S12} from C{._meanSinXi(Chix, Chiy) * .c2 * lon12}.
|
|
185
|
+
'''
|
|
186
|
+
pP, xD = self._RA, self._auxD
|
|
187
|
+
|
|
188
|
+
tx, Phix = Chix.tan, Chix.toPhi(self)
|
|
189
|
+
ty, Phiy = Chiy.tan, Chiy.toPhi(self)
|
|
190
|
+
|
|
191
|
+
dD = xD.DParametric(Phix, Phiy) if self.exact else \
|
|
192
|
+
xD.CParametric(Chix, Chiy)
|
|
193
|
+
if dD:
|
|
194
|
+
dD = _over(dD, xD.DIsometric(Phix, Phiy) if self.exact else
|
|
195
|
+
_Dlam(tx, ty)) # not Lambertian!
|
|
196
|
+
dD *= _DClenshaw(False, Phix.toBeta(self).normalized,
|
|
197
|
+
Phiy.toBeta(self).normalized,
|
|
198
|
+
pP, min(len(pP), xD.ALorder)) # Fsum
|
|
199
|
+
dD += _Dp0Dpsi(tx, ty)
|
|
200
|
+
dD *= self._c2 * lon12
|
|
201
|
+
return float(dD)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class RhumbLineAux(RhumbLineBase):
|
|
205
|
+
'''Compute one or several points on a single rhumb line.
|
|
206
|
+
|
|
207
|
+
Class C{RhumbLineAux} facilitates the determination of points
|
|
208
|
+
on a single rhumb line. The starting point (C{lat1}, C{lon1})
|
|
209
|
+
and the azimuth C{azi12} are specified once.
|
|
210
|
+
'''
|
|
211
|
+
_Rhumb = RhumbAux # rhumb.aux_.RhumbAux
|
|
212
|
+
|
|
213
|
+
def __init__(self, rhumb, lat1=0, lon1=0, azi12=None, **caps_name): # PYCHOK signature
|
|
214
|
+
'''New C{RhumbLineAux}.
|
|
215
|
+
|
|
216
|
+
@arg rhumb: The rhumb reference (L{RhumbAux}).
|
|
217
|
+
@kwarg lat1: Latitude of the start point (C{degrees90}).
|
|
218
|
+
@kwarg lon1: Longitude of the start point (C{degrees180}).
|
|
219
|
+
@kwarg azi12: Azimuth of this rhumb line (compass C{degrees}).
|
|
220
|
+
@kwarg caps_name: Optional keyword arguments C{B{name}=NN} and
|
|
221
|
+
C{B{caps}=0}, a bit-or'ed combination of L{Caps}
|
|
222
|
+
values specifying the required capabilities. Include
|
|
223
|
+
C{Caps.LINE_OFF} if updates to the B{C{rhumb}} should
|
|
224
|
+
I{not} be reflected in this rhumb line.
|
|
225
|
+
'''
|
|
226
|
+
RhumbLineBase.__init__(self, rhumb, lat1, lon1, azi12, **caps_name)
|
|
227
|
+
|
|
228
|
+
@Property_RO
|
|
229
|
+
def _Chi1(self):
|
|
230
|
+
return self._Phi1.toChi(self.rhumb)
|
|
231
|
+
|
|
232
|
+
@Property_RO
|
|
233
|
+
def _mu1(self):
|
|
234
|
+
'''(INTERNAL) Get the I{rectifying auxiliary} latitude (C{degrees}).
|
|
235
|
+
'''
|
|
236
|
+
return self._Phi1.toMu(self.rhumb).toDegrees
|
|
237
|
+
|
|
238
|
+
def _mu2lat(self, mu):
|
|
239
|
+
'''(INTERNAL) Get the inverse I{rectifying auxiliary} latitude (C{degrees}).
|
|
240
|
+
'''
|
|
241
|
+
lat, _ = self.rhumb._latPhi2(mu)
|
|
242
|
+
return lat
|
|
243
|
+
|
|
244
|
+
@Property_RO
|
|
245
|
+
def _Phi1(self):
|
|
246
|
+
return AuxPhi.fromDegrees(self.lat1)
|
|
247
|
+
|
|
248
|
+
def _Position4(self, a12, mu2, *unused): # PYCHOK s12, mu2
|
|
249
|
+
'''(INTERNAL) See method C{RhumbLineBase._Position}.
|
|
250
|
+
'''
|
|
251
|
+
R = self.rhumb
|
|
252
|
+
lat2, Phi2 = R._latPhi2(mu2)
|
|
253
|
+
Chi2 = Phi2.toChi(R)
|
|
254
|
+
Chi1 = self._Chi1
|
|
255
|
+
lon2 = self._salp * a12
|
|
256
|
+
if lon2:
|
|
257
|
+
m = R._DMu_DPsi(self._Phi1, Phi2, Chi1, Chi2)
|
|
258
|
+
lon2 = _over(lon2, m)
|
|
259
|
+
return lat2, lon2, Chi1, Chi2
|
|
260
|
+
|
|
261
|
+
# @Property_RO
|
|
262
|
+
# def _psi1(self):
|
|
263
|
+
# return self._Chi1.toLambertianRadians
|
|
264
|
+
|
|
265
|
+
RhumbAux._RhumbLine = RhumbLineAux # PYCHOK see RhumbBase._RhumbLine
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _RAintegrate(auxD):
|
|
269
|
+
# Compute coefficients by Fourier transform of integrand
|
|
270
|
+
L = 2
|
|
271
|
+
fft = _MODS.auxilats.auxDST.AuxDST(L)
|
|
272
|
+
f = auxD._qIntegrand
|
|
273
|
+
c_ = fft.transform(f)
|
|
274
|
+
pP = []
|
|
275
|
+
_P = pP.append
|
|
276
|
+
# assert L < _Lbits
|
|
277
|
+
while L < _Lbits:
|
|
278
|
+
L = fft.reset(L) * 2
|
|
279
|
+
c_ = fft.refine(f, c_, _0_0) # sentine[L]
|
|
280
|
+
# assert len(c_) == L + 1
|
|
281
|
+
pP[:], k = [], -1
|
|
282
|
+
for j in range(1, L + 1):
|
|
283
|
+
# Compute Fourier coefficients of integral
|
|
284
|
+
p = (c_[j - 1] + c_[j]) / (_4_0 * j)
|
|
285
|
+
if fabs(p) > EPS_2:
|
|
286
|
+
k = -1 # run interrupted
|
|
287
|
+
else:
|
|
288
|
+
if k < 0:
|
|
289
|
+
k = 1 # mark as first small value
|
|
290
|
+
if (j - k) >= ((j + 7) // 8):
|
|
291
|
+
# run of at least (j - 1) // 8 small values
|
|
292
|
+
return pP[:j] # break while L loop
|
|
293
|
+
_P(-p)
|
|
294
|
+
return pP # no convergence, use pP as-is
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def _RAseries(auxD):
|
|
298
|
+
# Series expansions in n for Fourier coeffients of the integral
|
|
299
|
+
# @see: U{"Series expansions for computing rhumb areas"
|
|
300
|
+
# <https:#DOI.org/10.5281/zenodo.7685484>}.
|
|
301
|
+
d = n = auxD._n
|
|
302
|
+
i = 0
|
|
303
|
+
aL = auxD.ALorder
|
|
304
|
+
Cs = _RACoeffs[aL]
|
|
305
|
+
# assert len(Cs) == (aL * (aL + 1)) // 2
|
|
306
|
+
pP = []
|
|
307
|
+
_P = pP.append
|
|
308
|
+
_p = _polynomial
|
|
309
|
+
for m in _reverange(aL): # order
|
|
310
|
+
j = i + m + 1
|
|
311
|
+
_P(_p(n, Cs, i, j) * d)
|
|
312
|
+
d *= n
|
|
313
|
+
i = j
|
|
314
|
+
# assert i == len(pP)
|
|
315
|
+
return pP
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
_f, _u = float, _Ufloats()
|
|
319
|
+
_RACoeffs = { # Rhumb Area Coefficients in matrix Q
|
|
320
|
+
4: _u( # GEOGRAPHICLIB_RHUMBAREA_ORDER == 4
|
|
321
|
+
596 / _f(2025), -398 / _f(945), 22 / _f(45), -1 / _f(3),
|
|
322
|
+
1543 / _f(4725), -118 / _f(315), 1 / _f(5),
|
|
323
|
+
152 / _f(945), -17 / _f(315),
|
|
324
|
+
5 / _f(252)),
|
|
325
|
+
5: _u( # GEOGRAPHICLIB_RHUMBAREA_ORDER == 5
|
|
326
|
+
-102614 / _f(467775), 596 / _f(2025), -398 / _f(945), 22 / _f(45),
|
|
327
|
+
-1 / _f(3),
|
|
328
|
+
-24562 / _f(155925), 1543 / _f(4725), -118 / _f(315), 1 / _f(5),
|
|
329
|
+
-38068 / _f(155925), 152 / _f(945), -17 / _f(315),
|
|
330
|
+
-752 / _f(10395), 5 / _f(252),
|
|
331
|
+
-101 / _f(17325)),
|
|
332
|
+
6: _u( # GEOGRAPHICLIB_RHUMBAREA_ORDER == 6
|
|
333
|
+
138734126 / _f(638512875), -102614 / _f(467775), 596 / _f(2025),
|
|
334
|
+
-398 / _f(945), 22 / _f(45), -1 / _f(3),
|
|
335
|
+
17749373 / _f(425675250), -24562 / _f(155925), 1543 / _f(4725),
|
|
336
|
+
-118 / _f(315), 1 / _f(5),
|
|
337
|
+
1882432 / _f(8513505), -38068 / _f(155925), 152 / _f(945),
|
|
338
|
+
-17 / _f(315),
|
|
339
|
+
268864 / _f(2027025), -752 / _f(10395), 5 / _f(252),
|
|
340
|
+
62464 / _f(2027025), -101 / _f(17325),
|
|
341
|
+
11537 / _f(4054050)),
|
|
342
|
+
7: _u( # GEOGRAPHICLIB_RHUMBAREA_ORDER == 7
|
|
343
|
+
-565017322 / _f(1915538625), 138734126 / _f(638512875),
|
|
344
|
+
-102614 / _f(467775), 596 / _f(2025), -398 / _f(945), 22 / _f(45),
|
|
345
|
+
-1 / _f(3),
|
|
346
|
+
-1969276 / _f(58046625), 17749373 / _f(425675250), -24562 / _f(155925),
|
|
347
|
+
1543 / _f(4725), -118 / _f(315), 1 / _f(5),
|
|
348
|
+
-58573784 / _f(638512875), 1882432 / _f(8513505), -38068 / _f(155925),
|
|
349
|
+
152 / _f(945), -17 / _f(315),
|
|
350
|
+
-6975184 / _f(42567525), 268864 / _f(2027025), -752 / _f(10395),
|
|
351
|
+
5 / _f(252),
|
|
352
|
+
-112832 / _f(1447875), 62464 / _f(2027025), -101 / _f(17325),
|
|
353
|
+
-4096 / _f(289575), 11537 / _f(4054050),
|
|
354
|
+
-311 / _f(525525)),
|
|
355
|
+
8: _u( # GEOGRAPHICLIB_RHUMBAREA_ORDER == 8
|
|
356
|
+
188270561816 / _f(488462349375), -565017322 / _f(1915538625),
|
|
357
|
+
138734126 / _f(638512875), -102614 / _f(467775), 596 / _f(2025),
|
|
358
|
+
-398 / _f(945), 22 / _f(45), -1 / _f(3),
|
|
359
|
+
2332829602 / _f(23260111875), -1969276 / _f(58046625),
|
|
360
|
+
17749373 / _f(425675250), -24562 / _f(155925), 1543 / _f(4725),
|
|
361
|
+
-118 / _f(315), 1 / _f(5),
|
|
362
|
+
-41570288 / _f(930404475), -58573784 / _f(638512875),
|
|
363
|
+
1882432 / _f(8513505), -38068 / _f(155925), 152 / _f(945),
|
|
364
|
+
-17 / _f(315),
|
|
365
|
+
1538774036 / _f(10854718875), -6975184 / _f(42567525),
|
|
366
|
+
268864 / _f(2027025), -752 / _f(10395), 5 / _f(252),
|
|
367
|
+
436821248 / _f(3618239625), -112832 / _f(1447875),
|
|
368
|
+
62464 / _f(2027025), -101 / _f(17325),
|
|
369
|
+
3059776 / _f(80405325), -4096 / _f(289575), 11537 / _f(4054050),
|
|
370
|
+
4193792 / _f(723647925), -311 / _f(525525),
|
|
371
|
+
1097653 / _f(1929727800))
|
|
372
|
+
}
|
|
373
|
+
del _f, _u, _Ufloats
|
|
374
|
+
|
|
375
|
+
__all__ += _ALL_DOCS(Caps)
|
|
376
|
+
|
|
377
|
+
# **) MIT License
|
|
378
|
+
#
|
|
379
|
+
# Copyright (C) 2023-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
380
|
+
#
|
|
381
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
382
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
383
|
+
# to deal in the Software without restriction, including without limitation
|
|
384
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
385
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
386
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
387
|
+
#
|
|
388
|
+
# The above copyright notice and this permission notice shall be included
|
|
389
|
+
# in all copies or substantial portions of the Software.
|
|
390
|
+
#
|
|
391
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
392
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
393
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
394
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
395
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
396
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
397
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|