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
pygeodesy/rhumb/solve.py
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
u'''Wrapper to invoke I{Karney}'s U{RhumbSolve
|
|
5
|
+
<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>} utility
|
|
6
|
+
as an (exact) rhumb or rhumb line from I{either GeographicLib 2.0 or 2.2+}.
|
|
7
|
+
|
|
8
|
+
@note: Set env variable C{PYGEODESY_RHUMBSOLVE} to the (fully qualified)
|
|
9
|
+
path of the C{RhumbSolve} executable.
|
|
10
|
+
'''
|
|
11
|
+
from pygeodesy.basics import _xinstanceof
|
|
12
|
+
from pygeodesy.constants import _0_0, _180_0, _N_180_0, _over, _90_0 # PYCHOK used!
|
|
13
|
+
from pygeodesy.errors import RhumbError # PYCHOK used!
|
|
14
|
+
from pygeodesy.interns import NN, _a12_, _azi12_, _lat2_, _lon2_, _s12_, _S12_, _UNDER_
|
|
15
|
+
from pygeodesy.karney import Caps, GDict, _norm180, Rhumb8Tuple, _sincos2d
|
|
16
|
+
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS, _getenv, \
|
|
17
|
+
_PYGEODESY_RHUMBSOLVE_
|
|
18
|
+
from pygeodesy.namedTuples import Destination3Tuple, Distance3Tuple
|
|
19
|
+
from pygeodesy.props import deprecated_method, Property, Property_RO
|
|
20
|
+
from pygeodesy.solveBase import _SolveBase, _SolveLineBase
|
|
21
|
+
from pygeodesy.utily import _unrollon, _Wrap, wrap360
|
|
22
|
+
|
|
23
|
+
__all__ = _ALL_LAZY.rhumb_solve
|
|
24
|
+
__version__ = '24.02.21'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class _RhumbSolveBase(_SolveBase):
|
|
28
|
+
'''(INTERNAL) Base class for L{RhumbSolve} and L{RhumbLineSolve}.
|
|
29
|
+
'''
|
|
30
|
+
_Error = RhumbError
|
|
31
|
+
_Names_Direct = _lat2_, _lon2_, _S12_
|
|
32
|
+
_Names_Inverse = _azi12_, _s12_, _S12_
|
|
33
|
+
_Solve_name = 'RhumbSolve'
|
|
34
|
+
_Solve_path = _getenv(_PYGEODESY_RHUMBSOLVE_, _PYGEODESY_RHUMBSOLVE_)
|
|
35
|
+
|
|
36
|
+
@Property_RO
|
|
37
|
+
def _cmdBasic(self):
|
|
38
|
+
'''(INTERNAL) Get the basic C{RhumbSolve} cmd (C{tuple}).
|
|
39
|
+
'''
|
|
40
|
+
return (self.RhumbSolve,) + self._e_option \
|
|
41
|
+
+ self._p_option \
|
|
42
|
+
+ self._s_option
|
|
43
|
+
|
|
44
|
+
@Property
|
|
45
|
+
def RhumbSolve(self):
|
|
46
|
+
'''Get the U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
47
|
+
executable (C{filename}).
|
|
48
|
+
'''
|
|
49
|
+
return self._Solve_path
|
|
50
|
+
|
|
51
|
+
@RhumbSolve.setter # PYCHOK setter!
|
|
52
|
+
def RhumbSolve(self, path):
|
|
53
|
+
'''Set the U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
54
|
+
executable (C{filename}), the (fully qualified) path to the C{RhumbSolve} executable.
|
|
55
|
+
|
|
56
|
+
@raise RhumbError: Invalid B{C{path}}, B{C{path}} doesn't exist or isn't
|
|
57
|
+
the C{RhumbSolve} executable.
|
|
58
|
+
'''
|
|
59
|
+
self._setSolve(path)
|
|
60
|
+
|
|
61
|
+
@Property_RO
|
|
62
|
+
def _s_option(self): # == not -E for GeodSolve
|
|
63
|
+
return () if self.Exact else ('-s',)
|
|
64
|
+
|
|
65
|
+
def toStr(self, **prec_sep): # PYCHOK signature
|
|
66
|
+
'''Return this C{RhumbSolve} as string.
|
|
67
|
+
|
|
68
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=', '}
|
|
69
|
+
for the C{float} C{prec}ision, number of decimal digits
|
|
70
|
+
(0..9) and the C{sep}arator string to join. Trailing
|
|
71
|
+
zero decimals are stripped for B{C{prec}} values of
|
|
72
|
+
1 and above, but kept for negative B{C{prec}} values.
|
|
73
|
+
|
|
74
|
+
@return: RhumbSolve items (C{str}).
|
|
75
|
+
'''
|
|
76
|
+
return self._toStr(RhumbSolve=self.RhumbSolve, **prec_sep)
|
|
77
|
+
|
|
78
|
+
# @Property_RO
|
|
79
|
+
# def _u_option(self):
|
|
80
|
+
# return '-u' if self.unroll else ()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class RhumbSolve(_RhumbSolveBase):
|
|
84
|
+
'''Wrapper to invoke I{Karney}'s U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
85
|
+
like a class, similar to L{pygeodesy.Rhumb} and L{pygeodesy.RhumbAux}.
|
|
86
|
+
|
|
87
|
+
@note: Use property C{RhumbSolve} or env variable C{PYGEODESY_RHUMBSOLVE} to specify the (fully
|
|
88
|
+
qualified) path to the C{RhumbSolve} executable.
|
|
89
|
+
|
|
90
|
+
@note: This C{rhumb} is intended I{for testing purposes only}, it invokes the C{RhumbSolve}
|
|
91
|
+
executable for I{every} method call.
|
|
92
|
+
'''
|
|
93
|
+
# def Area(self, polyline=False, name=NN):
|
|
94
|
+
# '''Set up a L{RhumbArea} to compute area and
|
|
95
|
+
# perimeter of a polygon.
|
|
96
|
+
#
|
|
97
|
+
# @kwarg polyline: If C{True} perimeter only, otherwise
|
|
98
|
+
# area and perimeter (C{bool}).
|
|
99
|
+
# @kwarg name: Optional name (C{str}).
|
|
100
|
+
#
|
|
101
|
+
# @return: A L{RhumbArea} instance.
|
|
102
|
+
#
|
|
103
|
+
# @note: The B{C{debug}} setting is passed as C{verbose}
|
|
104
|
+
# to the returned L{RhumbAreaExact} instance.
|
|
105
|
+
# '''
|
|
106
|
+
# rA = _MODS.rhumbs.rhumb*.RhumbArea(self, polyline=polyline,
|
|
107
|
+
# name=name or self.name)
|
|
108
|
+
# if self.verbose or self.debug: # PYCHOK no cover
|
|
109
|
+
# rA.verbose = True
|
|
110
|
+
# return rA
|
|
111
|
+
|
|
112
|
+
# Polygon = Area # for C{geographiclib} compatibility
|
|
113
|
+
|
|
114
|
+
def _azimuth_reverse(self, azimuth):
|
|
115
|
+
'''(INTERNAL) Reverse final azimuth C{azimuth}.
|
|
116
|
+
'''
|
|
117
|
+
z = _norm180(float(azimuth))
|
|
118
|
+
if self.reverse2: # like .utils.atan2d
|
|
119
|
+
z += _180_0 if z < 0 else _N_180_0
|
|
120
|
+
return z
|
|
121
|
+
|
|
122
|
+
def _Direct(self, ll1, azi12, s12, **outmask):
|
|
123
|
+
'''(INTERNAL) Short-cut version, see .latlonBase.
|
|
124
|
+
'''
|
|
125
|
+
return self.Direct(ll1.lat, ll1.lon, azi12, s12, **outmask)
|
|
126
|
+
|
|
127
|
+
def Direct3(self, lat1, lon1, azi1, s12): # PYCHOK outmask
|
|
128
|
+
'''Return the destination lat, lon and reverse azimuth
|
|
129
|
+
(final bearing) in C{degrees}.
|
|
130
|
+
|
|
131
|
+
@return: L{Destination3Tuple}C{(lat, lon, final)}.
|
|
132
|
+
'''
|
|
133
|
+
r = self._GDictDirect(lat1, lon1, azi1, False, s12, floats=False)
|
|
134
|
+
z = self._azimuth_reverse(r.azi12)
|
|
135
|
+
return Destination3Tuple(float(r.lat2), float(r.lon2), wrap360(z),
|
|
136
|
+
iteration=r._iteration)
|
|
137
|
+
|
|
138
|
+
def _DirectLine(self, ll1, azi12, **name_caps):
|
|
139
|
+
'''(INTERNAL) Short-cut version, see .latlonBase.
|
|
140
|
+
'''
|
|
141
|
+
return self.DirectLine(ll1.lat, ll1.lon, azi12, **name_caps)
|
|
142
|
+
|
|
143
|
+
def DirectLine(self, lat1, lon1, azi1, caps=Caps.STANDARD, name=NN):
|
|
144
|
+
'''Set up a L{RhumbLineSolve} in terms of the I{direct} rhumb
|
|
145
|
+
problem to compute several points on a single rhumb line.
|
|
146
|
+
|
|
147
|
+
@arg lat1: Latitude of the first point (C{degrees}).
|
|
148
|
+
@arg lon1: Longitude of the first point (C{degrees}).
|
|
149
|
+
@arg azi1: Azimuth at the first point (compass C{degrees}).
|
|
150
|
+
@kwarg caps: Bit-or'ed combination of L{Caps} values specifying
|
|
151
|
+
the capabilities the L{RhumbLineSolve} instance
|
|
152
|
+
should possess, always C{Caps.ALL}.
|
|
153
|
+
|
|
154
|
+
@return: A L{RhumbLineSolve} instance.
|
|
155
|
+
|
|
156
|
+
@note: If the point is at a pole, the azimuth is defined by keeping
|
|
157
|
+
B{C{lon1}} fixed, writing C{B{lat1} = ±(90 − ε)}, and taking
|
|
158
|
+
the limit C{ε → 0+}.
|
|
159
|
+
|
|
160
|
+
@see: C++ U{RhumbExact.Line
|
|
161
|
+
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1RhumbExact.html>}
|
|
162
|
+
and Python U{Rhumb.Line<https://GeographicLib.SourceForge.io/Python/doc/code.html>}.
|
|
163
|
+
'''
|
|
164
|
+
return RhumbLineSolve(self, lat1, lon1, azi1, caps=caps, name=name or self.name)
|
|
165
|
+
|
|
166
|
+
def _GDictDirect(self, lat, lon, azi1, arcmode, s12_a12, *unused, **floats): # PYCHOK signature
|
|
167
|
+
'''(INTERNAL) Get C{_GenDirect}-like result as an 8-item C{GDict}.
|
|
168
|
+
'''
|
|
169
|
+
d = _RhumbSolveBase._GDictDirect(self, lat, lon, azi1, arcmode, s12_a12, **floats)
|
|
170
|
+
r = GDict(lat1=lat, lon1=lon, azi12=azi1, s12=s12_a12) # a12=_over(s12_a12, self._mpd)
|
|
171
|
+
r.update(d)
|
|
172
|
+
return r
|
|
173
|
+
|
|
174
|
+
def _GDictInverse(self, lat1, lon1, lat2, lon2, *unused, **floats): # PYCHOK signature
|
|
175
|
+
'''(INTERNAL) Get C{_GenInverse}-like result as an 8-item C{GDict}, but
|
|
176
|
+
I{without} C{_SALPs_CALPs_}.
|
|
177
|
+
'''
|
|
178
|
+
i = _RhumbSolveBase._GDictInverse(self, lat1, lon1, lat2, lon2, **floats)
|
|
179
|
+
a = _over(float(i.s12), self._mpd) # for .Inverse1
|
|
180
|
+
r = GDict(lat1=lat1, lon1=lon1, lat2=lat2, lon2=lon2, a12=a)
|
|
181
|
+
r.update(i)
|
|
182
|
+
return r
|
|
183
|
+
|
|
184
|
+
def _Inverse(self, ll1, ll2, wrap, **unused):
|
|
185
|
+
'''(INTERNAL) Short-cut version, see .latlonBase.
|
|
186
|
+
'''
|
|
187
|
+
if wrap:
|
|
188
|
+
ll2 = _unrollon(ll1, _Wrap.point(ll2))
|
|
189
|
+
return self._GDictInverse(ll1.lat, ll1.lon, ll2.lat, ll2.lon)
|
|
190
|
+
|
|
191
|
+
def Inverse3(self, lat1, lon1, lat2, lon2): # PYCHOK outmask
|
|
192
|
+
'''Return the distance in C{meter} and the forward and
|
|
193
|
+
reverse azimuths (initial and final bearing) in C{degrees}.
|
|
194
|
+
|
|
195
|
+
@return: L{Distance3Tuple}C{(distance, initial, final)}.
|
|
196
|
+
'''
|
|
197
|
+
r = self._GDictInverse(lat1, lon1, lat2, lon2, floats=False)
|
|
198
|
+
z = self._azimuth_reverse(r.azi12)
|
|
199
|
+
return Distance3Tuple(float(r.s12), wrap360(r.azi12), wrap360(z),
|
|
200
|
+
iteration=r._iteration)
|
|
201
|
+
|
|
202
|
+
def _InverseLine(self, ll1, ll2, wrap, **name_caps):
|
|
203
|
+
'''(INTERNAL) Short-cut version, see .latlonBase.
|
|
204
|
+
'''
|
|
205
|
+
if wrap:
|
|
206
|
+
ll2 = _unrollon(ll1, _Wrap.point(ll2))
|
|
207
|
+
return self.InverseLine(ll1.lat, ll1.lon, ll2.lat, ll2.lon, **name_caps)
|
|
208
|
+
|
|
209
|
+
def InverseLine(self, lat1, lon1, lat2, lon2, caps=Caps.STANDARD, name=NN):
|
|
210
|
+
'''Define a L{RhumbLineSolve} in terms of the I{inverse}
|
|
211
|
+
rhumb problem.
|
|
212
|
+
|
|
213
|
+
@arg lat1: Latitude of the first point (C{degrees90}).
|
|
214
|
+
@arg lon1: Longitude of the first point (C{degrees180}).
|
|
215
|
+
@arg lat2: Latitude of the second point (C{degrees90}).
|
|
216
|
+
@arg lon2: Longitude of the second point (C{degrees180}).
|
|
217
|
+
@kwarg caps: Optional C{caps}, see L{RhumbLine} C{B{caps}}.
|
|
218
|
+
|
|
219
|
+
@return: A L{RhumbLineSolve} instance and invoke its method
|
|
220
|
+
L{RhumbLine.Position} to compute each point.
|
|
221
|
+
|
|
222
|
+
@note: Updates to this rhumb are reflected in the returned
|
|
223
|
+
rhumb line.
|
|
224
|
+
'''
|
|
225
|
+
r = self.Inverse(lat1, lon1, lat2, lon2) # outmask=Caps.AZIMUTH
|
|
226
|
+
return RhumbLineSolve(self, lat1, lon1, r.azi12, caps=caps,
|
|
227
|
+
name=name or self.name)
|
|
228
|
+
|
|
229
|
+
Line = DirectLine
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
class RhumbLineSolve(_RhumbSolveBase, _SolveLineBase):
|
|
233
|
+
'''Wrapper to invoke I{Karney}'s U{RhumbSolve<https://GeographicLib.SourceForge.io/C++/doc/RhumbSolve.1.html>}
|
|
234
|
+
like a class, similar to L{pygeodesy.RhumbLine} and L{pygeodesy.RhumbLineAux}.
|
|
235
|
+
|
|
236
|
+
@note: Use property C{RhumbSolve} or env variable C{PYGEODESY_RHUMBSOLVE} to specify the (fully
|
|
237
|
+
qualified) path to the C{RhumbSolve} executable.
|
|
238
|
+
|
|
239
|
+
@note: This C{rhumb line} is intended I{for testing purposes only}, it invokes the C{RhumbSolve}
|
|
240
|
+
executable for I{every} method call.
|
|
241
|
+
'''
|
|
242
|
+
def __init__(self, rhumb, lat1, lon1, azi12, caps=Caps.STANDARD, name=NN):
|
|
243
|
+
'''New L{RhumbLineSolve} instance, allowing points to be found along
|
|
244
|
+
a rhumb starting at C{(B{lat1}, B{lon1})} with azimuth B{C{azi12}}.
|
|
245
|
+
|
|
246
|
+
@arg rhumb: The rhumb to use (L{RhumbSolve}).
|
|
247
|
+
@arg lat1: Latitude of the first point (C{degrees90}).
|
|
248
|
+
@arg lon1: Longitude of the first point (C{degrees180}).
|
|
249
|
+
@arg azi12: Azimuth of the rhumb line (compass C{degrees180}).
|
|
250
|
+
@kwarg caps: Bit-or'ed combination of L{Caps} values specifying
|
|
251
|
+
the capabilities the L{RhumbLineSolve} instance should
|
|
252
|
+
possess, always C{Caps.ALL}. Use C{Caps.LINE_OFF}
|
|
253
|
+
if updates to the B{C{rhumb}} should I{not} be
|
|
254
|
+
reflected in this L{RhumbLineSolve} instance.
|
|
255
|
+
|
|
256
|
+
@kwarg name: Optional name (C{str}).
|
|
257
|
+
|
|
258
|
+
@raise RhumbError: Invalid path for C{RhumbSolve} executable or
|
|
259
|
+
isn't the C{RhumbSolve} executable, see
|
|
260
|
+
property C{B{rhumb}.RhumbSolve}.
|
|
261
|
+
|
|
262
|
+
@raise TypeError: Invalid B{C{rhumb}}.
|
|
263
|
+
'''
|
|
264
|
+
_xinstanceof(RhumbSolve, rhumb=rhumb)
|
|
265
|
+
if (caps & Caps.LINE_OFF): # copy to avoid updates
|
|
266
|
+
rhumb = rhumb.copy(deep=False, name=NN(_UNDER_, rhumb.name))
|
|
267
|
+
_SolveLineBase.__init__(self, rhumb, lat1, lon1, caps, name, azi12=azi12)
|
|
268
|
+
try:
|
|
269
|
+
self.RhumbSolve = rhumb.RhumbSolve # rhumb or copy of rhumb
|
|
270
|
+
except RhumbError:
|
|
271
|
+
pass
|
|
272
|
+
|
|
273
|
+
# def ArcPosition(self, a12, *unused):
|
|
274
|
+
# '''Find the position on the line given B{C{a12}}.
|
|
275
|
+
#
|
|
276
|
+
# @arg a12: Spherical arc length from the first point to the
|
|
277
|
+
# second point (C{degrees}).
|
|
278
|
+
#
|
|
279
|
+
# @return: A C{dict} with 8 items C{lat1, lon1, lat2, lon2,
|
|
280
|
+
# azi12, a12, s12, S12}.
|
|
281
|
+
# '''
|
|
282
|
+
# s = a12 * self._mpd
|
|
283
|
+
# a = self._GDictInvoke(self._cmdArc, True, self._Names_Direct, s)
|
|
284
|
+
# r = GDict(a12=a12, s12=s, **self._lla1)
|
|
285
|
+
# r.updated(a)
|
|
286
|
+
# return r
|
|
287
|
+
|
|
288
|
+
@Property_RO
|
|
289
|
+
def azi12(self):
|
|
290
|
+
'''Get this rhumb line's azimuth (compass C{degrees}).
|
|
291
|
+
'''
|
|
292
|
+
return self._lla1.azi12
|
|
293
|
+
|
|
294
|
+
azi1 = azi12 # like GeodesicLineSolve
|
|
295
|
+
|
|
296
|
+
@Property_RO
|
|
297
|
+
def azi12_sincos2(self): # PYCHOK no cover
|
|
298
|
+
'''Get the sine and cosine of this rhumb line's azimuth (2-tuple C{(sin, cos)}).
|
|
299
|
+
'''
|
|
300
|
+
return _sincos2d(self.azi12)
|
|
301
|
+
|
|
302
|
+
azi1_sincos2 = azi12_sincos2
|
|
303
|
+
|
|
304
|
+
# @Property_RO
|
|
305
|
+
# def _cmdArc(self):
|
|
306
|
+
# '''(INTERNAL) Get the C{RhumbSolve} I{-a -L} cmd (C{tuple}).
|
|
307
|
+
# '''
|
|
308
|
+
# return self._cmdDistance + ('-a',)
|
|
309
|
+
|
|
310
|
+
def Position(self, s12, **unused):
|
|
311
|
+
'''Find the position on the line given B{C{s12}}.
|
|
312
|
+
|
|
313
|
+
@arg s12: Distance from the first point to the second (C{meter}).
|
|
314
|
+
|
|
315
|
+
@return: A L{GDict} with 7 items C{lat1, lon1, lat2, lon2,
|
|
316
|
+
azi12, s12, S12}.
|
|
317
|
+
'''
|
|
318
|
+
d = self._GDictInvoke(self._cmdDistance, True, self._Names_Direct, s12)
|
|
319
|
+
r = GDict(s12=s12, **self._lla1) # a12=_over(s12, self._mpd)
|
|
320
|
+
r.update(d)
|
|
321
|
+
return r
|
|
322
|
+
|
|
323
|
+
def toStr(self, **prec_sep): # PYCHOK signature
|
|
324
|
+
'''Return this C{RhumbLineSolve} as string.
|
|
325
|
+
|
|
326
|
+
@kwarg prec_sep: Keyword argumens C{B{prec}=6} and C{B{sep}=', '}
|
|
327
|
+
for the C{float} C{prec}ision, number of decimal digits
|
|
328
|
+
(0..9) and the C{sep}arator string to join. Trailing
|
|
329
|
+
zero decimals are stripped for B{C{prec}} values of
|
|
330
|
+
1 and above, but kept for negative B{C{prec}} values.
|
|
331
|
+
|
|
332
|
+
@return: RhumbLineSolve items (C{str}).
|
|
333
|
+
'''
|
|
334
|
+
return _SolveLineBase._toStr(self, azi12=self.azi12, rhumb=self._solve,
|
|
335
|
+
RhumbSolve=self.RhumbSolve, **prec_sep)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
class RhumbSolve7Tuple(Rhumb8Tuple):
|
|
339
|
+
'''7-Tuple C{(lat1, lon1, lat2, lon2, azi12, s12, S12)} with lat- C{lat1},
|
|
340
|
+
C{lat2} and longitudes C{lon1}, C{lon2} of both points, the azimuth of
|
|
341
|
+
the rhumb line C{azi12}, the distance C{s12} and the area C{S12} under
|
|
342
|
+
the rhumb line between both points.
|
|
343
|
+
'''
|
|
344
|
+
assert Rhumb8Tuple._Names_.index(_a12_) == 7
|
|
345
|
+
_Names_ = Rhumb8Tuple._Names_[:7] # drop a12
|
|
346
|
+
_Units_ = Rhumb8Tuple._Units_[:7]
|
|
347
|
+
|
|
348
|
+
@deprecated_method
|
|
349
|
+
def _to7Tuple(self): # PYCHOK no cover
|
|
350
|
+
'''DEPRECATED, I{don't use!}
|
|
351
|
+
'''
|
|
352
|
+
return _MODS.deprecated.classes.Rhumb7Tuple(self[:7])
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
__all__ += _ALL_DOCS(_RhumbSolveBase)
|
|
356
|
+
|
|
357
|
+
if __name__ == '__main__':
|
|
358
|
+
|
|
359
|
+
from pygeodesy.lazily import printf
|
|
360
|
+
from sys import argv
|
|
361
|
+
|
|
362
|
+
def rhumb_intercept(rS, lat1, lon1, lat2, lon2, azi2, s23):
|
|
363
|
+
# using RhumbSolve and GeodesicExact for I{Karney}'s C++ U{rhumb-intercept.cpp
|
|
364
|
+
# <https://SourceForge.net/p/geographiclib/discussion/1026620/thread/2ddc295e/>
|
|
365
|
+
from pygeodesy.constants import EPS4 as _TOL
|
|
366
|
+
from pygeodesy.karney import _diff182
|
|
367
|
+
|
|
368
|
+
E = rS.ellipsoid
|
|
369
|
+
gX = E.geodesicx # == GeodesicExact(E)
|
|
370
|
+
m = gX.STANDARD | gX.REDUCEDLENGTH | gX.GEODESICSCALE
|
|
371
|
+
|
|
372
|
+
rlS = rS.Line(lat2, lon2, azi2)
|
|
373
|
+
sa, _ = rlS.azi12_sincos2 # aka _salp, _calp
|
|
374
|
+
for i in range(1, 16):
|
|
375
|
+
p = rlS.Position(s23) # outmask=gX.LATITUDE_LONGITUDE
|
|
376
|
+
r = gX.Inverse(lat1, lon1, p.lat2, p.lon2, outmask=m)
|
|
377
|
+
d, _ = _diff182(azi2, r.azi2, K_2_0=True)
|
|
378
|
+
s, c = _sincos2d(d)
|
|
379
|
+
printf('%2d %.3f %.8f, %.8f, %.8e',
|
|
380
|
+
i, s23, r.lat2, r.lon2, c)
|
|
381
|
+
s2, c2 = _sincos2d(r.lat2)
|
|
382
|
+
c2 *= E.rocTransverse(r.lat2)
|
|
383
|
+
if c2 and r.m12:
|
|
384
|
+
s *= (s2 * sa) / c2 - s * r.M21 / r.m12
|
|
385
|
+
t = (c / s) if s else _0_0
|
|
386
|
+
if abs(t) < _TOL:
|
|
387
|
+
break
|
|
388
|
+
s23 += t
|
|
389
|
+
else:
|
|
390
|
+
break
|
|
391
|
+
|
|
392
|
+
rS = RhumbSolve(name='Test')
|
|
393
|
+
rS.verbose = '--verbose' in argv # or '-v' in argv
|
|
394
|
+
|
|
395
|
+
if rS.RhumbSolve in (_PYGEODESY_RHUMBSOLVE_, None): # not set
|
|
396
|
+
rS.RhumbSolve = '/opt/local/bin/RhumbSolve' # '/opt/local/Cellar/geographiclib/2.2/bin/RhumbSolve' # HomeBrew
|
|
397
|
+
printf('version: %s', rS.version)
|
|
398
|
+
|
|
399
|
+
if len(argv) > 6: # 60 0 30 0 45 1e6
|
|
400
|
+
t = (14, 's23'), (7, 'lat3'), (11, 'lon3'), (13, 'cos()')
|
|
401
|
+
printf(' '.join('%*s' % _ for _ in t))
|
|
402
|
+
rhumb_intercept(rS, *map(float, argv[-6:]))
|
|
403
|
+
exit()
|
|
404
|
+
|
|
405
|
+
r = rS.Direct(40.6, -73.8, 51, 5.5e6)
|
|
406
|
+
printf('Direct: %r', r, nl=1)
|
|
407
|
+
printf('Direct3: %r', rS.Direct3(40.6, -73.8, 51, 5.5e6))
|
|
408
|
+
|
|
409
|
+
printf('Inverse: %r', rS.Inverse( 40.6, -73.8, 51.6, -0.5), nl=1)
|
|
410
|
+
printf('Inverse1: %r', rS.Inverse1(40.6, -73.8, 51.6, -0.5))
|
|
411
|
+
printf('Inverse3: %r', rS.Inverse3(40.6, -73.8, 51.6, -0.5))
|
|
412
|
+
|
|
413
|
+
printf('Inverse: %r', rS.Inverse( 40.6, -73.8, 35.8, 140.3), nl=1)
|
|
414
|
+
printf('Inverse1: %r', rS.Inverse1(40.6, -73.8, 35.8, 140.3))
|
|
415
|
+
printf('Inverse3: %r', rS.Inverse3(40.6, -73.8, 35.8, 140.3))
|
|
416
|
+
|
|
417
|
+
rlS = RhumbLineSolve(rS, 40.6, -73.8, 51, name='LineTest')
|
|
418
|
+
p = rlS.Position(5.5e6)
|
|
419
|
+
printf('Position: %s %r', p == r, p, nl=1)
|
|
420
|
+
# p = rlS.ArcPosition(49.475527)
|
|
421
|
+
# printf('ArcPosition: %s %r', p == r, p)
|
|
422
|
+
|
|
423
|
+
# % python3 -m pygeodesy.rhumb.solve
|
|
424
|
+
|
|
425
|
+
# version: /opt/local/bin/RhumbSolve: GeographicLib version 1.51
|
|
426
|
+
#
|
|
427
|
+
# Direct: GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
428
|
+
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
429
|
+
#
|
|
430
|
+
# 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)
|
|
431
|
+
# Inverse1: 51.92954250756195
|
|
432
|
+
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
433
|
+
#
|
|
434
|
+
# 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)
|
|
435
|
+
# Inverse1: 115.02061966879258
|
|
436
|
+
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
437
|
+
#
|
|
438
|
+
# Position: True GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
# % python3 -m pygeodesy.rhumb.solve --verbose
|
|
442
|
+
|
|
443
|
+
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve --version (invoke)
|
|
444
|
+
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve: GeographicLib version 1.51 (0)
|
|
445
|
+
# version: /opt/local/bin/RhumbSolve: GeographicLib version 1.51
|
|
446
|
+
# RhumbSolve 'Test' 2: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
|
|
447
|
+
# RhumbSolve 'Test' 2: lat2=71.688899882813047, lon2=0.255519824423445, S12=44095641862956.148 (0)
|
|
448
|
+
|
|
449
|
+
# Direct: GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
450
|
+
# RhumbSolve 'Test' 3: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
|
|
451
|
+
# RhumbSolve 'Test' 3: lat2=71.688899882813047, lon2=0.255519824423445, S12=44095641862956.148 (0)
|
|
452
|
+
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
453
|
+
# RhumbSolve 'Test' 4: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
|
|
454
|
+
# RhumbSolve 'Test' 4: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
455
|
+
|
|
456
|
+
# 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)
|
|
457
|
+
# RhumbSolve 'Test' 5: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
|
|
458
|
+
# RhumbSolve 'Test' 5: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
459
|
+
# Inverse1: 51.92954250756195
|
|
460
|
+
# RhumbSolve 'Test' 6: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
|
|
461
|
+
# RhumbSolve 'Test' 6: azi12=77.768389710255661, s12=5771083.3833280317, S12=37395209100030.367 (0)
|
|
462
|
+
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
463
|
+
# RhumbSolve 'Test' 7: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse)
|
|
464
|
+
# RhumbSolve 'Test' 7: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
465
|
+
|
|
466
|
+
# 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)
|
|
467
|
+
# RhumbSolve 'Test' 8: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse1)
|
|
468
|
+
# RhumbSolve 'Test' 8: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
469
|
+
# Inverse1: 115.02061966879258
|
|
470
|
+
# RhumbSolve 'Test' 9: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse3)
|
|
471
|
+
# RhumbSolve 'Test' 9: azi12=-92.388887981699639, s12=12782581.0676841792, S12=-63760642939072.492 (0)
|
|
472
|
+
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
473
|
+
|
|
474
|
+
# Position: True GDict(S12=44095641862956.148438, azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
# % python3 -m pygeodesy.rhumb.solve
|
|
478
|
+
|
|
479
|
+
# version: /opt/local/bin/RhumbSolve: GeographicLib version 2.2
|
|
480
|
+
|
|
481
|
+
# Direct: GDict(azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0, S12=44095641862956.109375)
|
|
482
|
+
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
483
|
+
|
|
484
|
+
# 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)
|
|
485
|
+
# Inverse1: 51.92954250756191
|
|
486
|
+
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
487
|
+
|
|
488
|
+
# 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)
|
|
489
|
+
# Inverse1: 115.02061966879249
|
|
490
|
+
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
491
|
+
|
|
492
|
+
# Position: True GDict(azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0, S12=44095641862956.109375)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
# % python3 -m pygeodesy.rhumb.solve --verbose
|
|
496
|
+
|
|
497
|
+
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve --version (invoke)
|
|
498
|
+
# RhumbSolve 'Test' 1: /opt/local/bin/RhumbSolve: GeographicLib version 2.2 (0)
|
|
499
|
+
# version: /opt/local/bin/RhumbSolve: GeographicLib version 2.2
|
|
500
|
+
# RhumbSolve 'Test' 2: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct)
|
|
501
|
+
# RhumbSolve 'Test' 2: lat2=71.688899882813018, lon2=0.255519824423402, S12=44095641862956.109 (0)
|
|
502
|
+
|
|
503
|
+
# Direct: GDict(azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0, S12=44095641862956.109375)
|
|
504
|
+
# RhumbSolve 'Test' 3: /opt/local/bin/RhumbSolve -p 10 \ 40.600000000000001 -73.799999999999997 51.0 5500000.0 (Direct3)
|
|
505
|
+
# RhumbSolve 'Test' 3: lat2=71.688899882813018, lon2=0.255519824423402, S12=44095641862956.109 (0)
|
|
506
|
+
# Direct3: Destination3Tuple(lat=71.6889, lon=0.25552, final=51.0)
|
|
507
|
+
# RhumbSolve 'Test' 4: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse)
|
|
508
|
+
# RhumbSolve 'Test' 4: azi12=77.768389710255661, s12=5771083.383328028, S12=37395209100030.391 (0)
|
|
509
|
+
|
|
510
|
+
# 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)
|
|
511
|
+
# RhumbSolve 'Test' 5: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse1)
|
|
512
|
+
# RhumbSolve 'Test' 5: azi12=77.768389710255661, s12=5771083.383328028, S12=37395209100030.391 (0)
|
|
513
|
+
# Inverse1: 51.92954250756191
|
|
514
|
+
# RhumbSolve 'Test' 6: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 51.600000000000001 -0.5 (Inverse3)
|
|
515
|
+
# RhumbSolve 'Test' 6: azi12=77.768389710255661, s12=5771083.383328028, S12=37395209100030.391 (0)
|
|
516
|
+
# Inverse3: Distance3Tuple(distance=5771083.383328, initial=77.76839, final=77.76839)
|
|
517
|
+
# RhumbSolve 'Test' 7: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse)
|
|
518
|
+
# RhumbSolve 'Test' 7: azi12=-92.388887981699654, s12=12782581.0676841699, S12=-63760642939072.5 (0)
|
|
519
|
+
|
|
520
|
+
# 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)
|
|
521
|
+
# RhumbSolve 'Test' 8: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse1)
|
|
522
|
+
# RhumbSolve 'Test' 8: azi12=-92.388887981699654, s12=12782581.0676841699, S12=-63760642939072.5 (0)
|
|
523
|
+
# Inverse1: 115.02061966879249
|
|
524
|
+
# RhumbSolve 'Test' 9: /opt/local/bin/RhumbSolve -p 10 -i \ 40.600000000000001 -73.799999999999997 35.799999999999997 140.300000000000011 (Inverse3)
|
|
525
|
+
# RhumbSolve 'Test' 9: azi12=-92.388887981699654, s12=12782581.0676841699, S12=-63760642939072.5 (0)
|
|
526
|
+
# Inverse3: Distance3Tuple(distance=12782581.067684, initial=267.611112, final=267.611112)
|
|
527
|
+
|
|
528
|
+
# Position: True GDict(azi12=51, lat1=40.6, lat2=71.6889, lon1=-73.8, lon2=0.25552, s12=5500000.0, S12=44095641862956.109375)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
# % python3 -m pygeodesy.rhumb.solve 60 0 30 0 45 1e6
|
|
532
|
+
|
|
533
|
+
# version: /opt/local/bin/RhumbSolve: GeographicLib version 2.2
|
|
534
|
+
# s23 lat3 lon3 cos()
|
|
535
|
+
# 1 1000000.000 36.37559999, 7.58982303, -5.83098638e-01
|
|
536
|
+
# 2 4532573.097 58.84251798, 41.57078946, 4.05349594e-01
|
|
537
|
+
# 3 2233216.895 44.22871762, 17.86660260, -2.91432608e-01
|
|
538
|
+
# 4 3168401.173 50.17678842, 26.60741388, 3.00555188e-02
|
|
539
|
+
# 5 3082690.347 49.63189746, 25.76374255, -1.49446251e-04
|
|
540
|
+
# 6 3083112.629 49.63458216, 25.76787599, -2.59865190e-09
|
|
541
|
+
# 7 3083112.636 49.63458221, 25.76787606, 4.96052409e-16
|
|
542
|
+
# 8 3083112.636 49.63458221, 25.76787606, -4.96052409e-16
|
|
543
|
+
# 9 3083112.636 49.63458221, 25.76787606, 4.96052409e-16
|
|
544
|
+
# 10 3083112.636 49.63458221, 25.76787606, -4.96052409e-16
|
|
545
|
+
# 11 3083112.636 49.63458221, 25.76787606, 4.96052409e-16
|
|
546
|
+
# 12 3083112.636 49.63458221, 25.76787606, -4.96052409e-16
|
|
547
|
+
# 13 3083112.636 49.63458221, 25.76787606, 4.96052409e-16
|
|
548
|
+
# 14 3083112.636 49.63458221, 25.76787606, -4.96052409e-16
|
|
549
|
+
# 15 3083112.636 49.63458221, 25.76787606, 4.96052409e-16
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
# **) MIT License
|
|
553
|
+
#
|
|
554
|
+
# Copyright (C) 2022-2024 -- mrJean1 at Gmail -- All Rights Reserved.
|
|
555
|
+
#
|
|
556
|
+
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
557
|
+
# copy of this software and associated documentation files (the "Software"),
|
|
558
|
+
# to deal in the Software without restriction, including without limitation
|
|
559
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
560
|
+
# and/or sell copies of the Software, and to permit persons to whom the
|
|
561
|
+
# Software is furnished to do so, subject to the following conditions:
|
|
562
|
+
#
|
|
563
|
+
# The above copyright notice and this permission notice shall be included
|
|
564
|
+
# in all copies or substantial portions of the Software.
|
|
565
|
+
#
|
|
566
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
567
|
+
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
568
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
569
|
+
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
570
|
+
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
571
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
572
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|