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.
Files changed (115) hide show
  1. PyGeodesy-24.3.24.dist-info/METADATA +272 -0
  2. PyGeodesy-24.3.24.dist-info/RECORD +115 -0
  3. PyGeodesy-24.3.24.dist-info/WHEEL +6 -0
  4. PyGeodesy-24.3.24.dist-info/top_level.txt +1 -0
  5. pygeodesy/LICENSE +21 -0
  6. pygeodesy/__init__.py +615 -0
  7. pygeodesy/__main__.py +103 -0
  8. pygeodesy/albers.py +867 -0
  9. pygeodesy/auxilats/_CX_4.py +218 -0
  10. pygeodesy/auxilats/_CX_6.py +314 -0
  11. pygeodesy/auxilats/_CX_8.py +475 -0
  12. pygeodesy/auxilats/__init__.py +54 -0
  13. pygeodesy/auxilats/__main__.py +86 -0
  14. pygeodesy/auxilats/auxAngle.py +548 -0
  15. pygeodesy/auxilats/auxDLat.py +302 -0
  16. pygeodesy/auxilats/auxDST.py +296 -0
  17. pygeodesy/auxilats/auxLat.py +848 -0
  18. pygeodesy/auxilats/auxily.py +272 -0
  19. pygeodesy/azimuthal.py +1150 -0
  20. pygeodesy/basics.py +892 -0
  21. pygeodesy/booleans.py +2031 -0
  22. pygeodesy/cartesianBase.py +1062 -0
  23. pygeodesy/clipy.py +704 -0
  24. pygeodesy/constants.py +516 -0
  25. pygeodesy/css.py +660 -0
  26. pygeodesy/datums.py +752 -0
  27. pygeodesy/deprecated/__init__.py +61 -0
  28. pygeodesy/deprecated/bases.py +40 -0
  29. pygeodesy/deprecated/classes.py +262 -0
  30. pygeodesy/deprecated/consterns.py +54 -0
  31. pygeodesy/deprecated/datum.py +40 -0
  32. pygeodesy/deprecated/functions.py +375 -0
  33. pygeodesy/deprecated/nvector.py +48 -0
  34. pygeodesy/deprecated/rhumbBase.py +32 -0
  35. pygeodesy/deprecated/rhumbaux.py +33 -0
  36. pygeodesy/deprecated/rhumbsolve.py +33 -0
  37. pygeodesy/deprecated/rhumbx.py +33 -0
  38. pygeodesy/dms.py +986 -0
  39. pygeodesy/ecef.py +1348 -0
  40. pygeodesy/elevations.py +279 -0
  41. pygeodesy/ellipsoidalBase.py +1224 -0
  42. pygeodesy/ellipsoidalBaseDI.py +913 -0
  43. pygeodesy/ellipsoidalExact.py +343 -0
  44. pygeodesy/ellipsoidalGeodSolve.py +343 -0
  45. pygeodesy/ellipsoidalKarney.py +403 -0
  46. pygeodesy/ellipsoidalNvector.py +685 -0
  47. pygeodesy/ellipsoidalVincenty.py +590 -0
  48. pygeodesy/ellipsoids.py +2476 -0
  49. pygeodesy/elliptic.py +1198 -0
  50. pygeodesy/epsg.py +243 -0
  51. pygeodesy/errors.py +804 -0
  52. pygeodesy/etm.py +1190 -0
  53. pygeodesy/fmath.py +1013 -0
  54. pygeodesy/formy.py +1818 -0
  55. pygeodesy/frechet.py +865 -0
  56. pygeodesy/fstats.py +760 -0
  57. pygeodesy/fsums.py +1898 -0
  58. pygeodesy/gars.py +358 -0
  59. pygeodesy/geodesicw.py +581 -0
  60. pygeodesy/geodesicx/_C4_24.py +1699 -0
  61. pygeodesy/geodesicx/_C4_27.py +2395 -0
  62. pygeodesy/geodesicx/_C4_30.py +3301 -0
  63. pygeodesy/geodesicx/__init__.py +48 -0
  64. pygeodesy/geodesicx/__main__.py +91 -0
  65. pygeodesy/geodesicx/gx.py +1382 -0
  66. pygeodesy/geodesicx/gxarea.py +535 -0
  67. pygeodesy/geodesicx/gxbases.py +154 -0
  68. pygeodesy/geodesicx/gxline.py +669 -0
  69. pygeodesy/geodsolve.py +426 -0
  70. pygeodesy/geohash.py +914 -0
  71. pygeodesy/geoids.py +1884 -0
  72. pygeodesy/hausdorff.py +892 -0
  73. pygeodesy/heights.py +1155 -0
  74. pygeodesy/interns.py +687 -0
  75. pygeodesy/iters.py +545 -0
  76. pygeodesy/karney.py +919 -0
  77. pygeodesy/ktm.py +633 -0
  78. pygeodesy/latlonBase.py +1766 -0
  79. pygeodesy/lazily.py +960 -0
  80. pygeodesy/lcc.py +684 -0
  81. pygeodesy/ltp.py +1107 -0
  82. pygeodesy/ltpTuples.py +1563 -0
  83. pygeodesy/mgrs.py +721 -0
  84. pygeodesy/named.py +1324 -0
  85. pygeodesy/namedTuples.py +683 -0
  86. pygeodesy/nvectorBase.py +695 -0
  87. pygeodesy/osgr.py +781 -0
  88. pygeodesy/points.py +1686 -0
  89. pygeodesy/props.py +628 -0
  90. pygeodesy/resections.py +1048 -0
  91. pygeodesy/rhumb/__init__.py +46 -0
  92. pygeodesy/rhumb/aux_.py +397 -0
  93. pygeodesy/rhumb/bases.py +1148 -0
  94. pygeodesy/rhumb/ekx.py +563 -0
  95. pygeodesy/rhumb/solve.py +572 -0
  96. pygeodesy/simplify.py +647 -0
  97. pygeodesy/solveBase.py +472 -0
  98. pygeodesy/sphericalBase.py +724 -0
  99. pygeodesy/sphericalNvector.py +1264 -0
  100. pygeodesy/sphericalTrigonometry.py +1447 -0
  101. pygeodesy/streprs.py +627 -0
  102. pygeodesy/trf.py +2079 -0
  103. pygeodesy/triaxials.py +1484 -0
  104. pygeodesy/units.py +969 -0
  105. pygeodesy/unitsBase.py +349 -0
  106. pygeodesy/ups.py +538 -0
  107. pygeodesy/utily.py +1231 -0
  108. pygeodesy/utm.py +762 -0
  109. pygeodesy/utmups.py +318 -0
  110. pygeodesy/utmupsBase.py +517 -0
  111. pygeodesy/vector2d.py +785 -0
  112. pygeodesy/vector3d.py +968 -0
  113. pygeodesy/vector3dBase.py +1049 -0
  114. pygeodesy/webmercator.py +383 -0
  115. pygeodesy/wgrs.py +439 -0
@@ -0,0 +1,683 @@
1
+
2
+ # -*- coding: utf-8 -*-
3
+
4
+ u'''Named tuples.
5
+
6
+ Tuples returned by C{pygeodesy} functions and class methods
7
+ are all instances of some C{Named...Tuple} class, all sub-classes
8
+ of C{_NamedTuple} defined in C{pygeodesy.named}.
9
+ '''
10
+
11
+ from pygeodesy.basics import map1, _xinstanceof
12
+ # from pygeodesy.constants import INT0 # from .units
13
+ from pygeodesy.errors import _ALL_LAZY, _MODS, _xattr, _xkwds_not # _xkwds
14
+ from pygeodesy.interns import NN, _1_, _2_, _a_, _A_, _area_, _angle_, _b_, \
15
+ _B_, _band_, _c_, _C_, _datum_, _D_, _distance_, \
16
+ _E_, _easting_, _end_, _fi_, _gamma_, _height_, \
17
+ _h_, _j_, _hemipole_, _initial_, _lam_, _lat_, \
18
+ _lon_, _n_, _northing_, _number_, _outside_, \
19
+ _phi_, _point_, _precision_, _points_, _radius_, \
20
+ _scale_, _start_, _x_, _y_, _z_, _zone_
21
+ # from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .errors
22
+ from pygeodesy.named import _NamedTuple, _Pass
23
+ from pygeodesy.props import deprecated_property_RO, property_RO
24
+ from pygeodesy.units import Band, Bearing, Degrees, Degrees2, Easting, \
25
+ FIx, Height, Int, INT0, Lam, Lat, Lon, Meter, \
26
+ Meter2, Northing, Number_, Phi, Precision_, \
27
+ Radians, Radius, Scalar, Str
28
+
29
+ __all__ = _ALL_LAZY.namedTuples
30
+ __version__ = '23.12.07'
31
+
32
+ # __DUNDER gets mangled in class
33
+ _closest_ = 'closest'
34
+ _destination_ = 'destination'
35
+ _elel_ = 'll'
36
+ _final_ = 'final'
37
+ _fraction_ = 'fraction'
38
+
39
+
40
+ class Bearing2Tuple(_NamedTuple):
41
+ '''2-Tuple C{(initial, final)} bearings, both in compass C{degrees360}.
42
+ '''
43
+ _Names_ = (_initial_, _final_)
44
+ _Units_ = ( Bearing, Bearing)
45
+
46
+
47
+ class Bounds2Tuple(_NamedTuple): # .geohash.py, .latlonBase.py, .points.py
48
+ '''2-Tuple C{(latlonSW, latlonNE)} with the bounds' lower-left and
49
+ upper-right corner as C{LatLon} instance.
50
+ '''
51
+ _Names_ = ('latlonSW', 'latlonNE')
52
+ _Units_ = (_Pass, _Pass)
53
+
54
+
55
+ class Bounds4Tuple(_NamedTuple): # .geohash.py, .points.py
56
+ '''4-Tuple C{(latS, lonW, latN, lonE)} with the bounds' lower-left
57
+ C{(LatS, LowW)} and upper-right C{(latN, lonE)} corner lat- and
58
+ longitudes.
59
+ '''
60
+ _Names_ = ('latS', 'lonW', 'latN', 'lonE')
61
+ _Units_ = ( Lat, Lon, Lat, Lon)
62
+
63
+ def enclosures(self, S_other, *W_N_E):
64
+ '''Get the enclosures of this around an other L{Bounds4Tuple}.
65
+
66
+ @arg S_other: Bottom C{latS} (C{scalar}) or an other
67
+ L{Bounds4Tuple} instance.
68
+ @arg W_N_E: Left C{lonW}, top C{latN} and right C{lonE},
69
+ each a (C{scalar}) for C{scalar B{S_other}}.
70
+
71
+ @return: A L{Bounds4Tuple} with the I{margin} at each of
72
+ the 4 sides, positive if this side I{encloses}
73
+ (is on the I{outside} of) the other, negative
74
+ if not or zero if abutting.
75
+ '''
76
+ s, w, n, e = self
77
+ S, W, N, E = map1(float, S_other, *W_N_E) if W_N_E else S_other
78
+ return Bounds4Tuple(map1(float, S - s, W - w, n - N, e - E)) # *map1
79
+
80
+ def overlap(self, S_other, *W_N_E):
81
+ '''Intersect this with an other L{Bounds4Tuple}.
82
+
83
+ @arg S_other: Bottom C{latS} (C{scalar}) or an other
84
+ L{Bounds4Tuple} instance.
85
+ @arg W_N_E: Left C{lonW}, top C{latN} and right C{lonE},
86
+ each a (C{scalar}) for C{scalar B{S_other}}.
87
+
88
+ @return: C{None} if the bounds do not overlap, otherwise
89
+ the intersection of both as a L{Bounds4Tuple}.
90
+ '''
91
+ s, w, n, e = self
92
+ S, W, N, E = map1(float, S_other, *W_N_E) if W_N_E else S_other
93
+ return None if s > N or n < S or w > E or e < W else \
94
+ Bounds4Tuple(max(s, S), max(w, W), min(n, N), min(e, E))
95
+
96
+
97
+ class Destination2Tuple(_NamedTuple): # .ellipsoidalKarney.py, -Vincenty.py
98
+ '''2-Tuple C{(destination, final)}, C{destination} in C{LatLon}
99
+ and C{final} bearing in compass C{degrees360}.
100
+ '''
101
+ _Names_ = (_destination_, _final_)
102
+ _Units_ = (_Pass, Bearing)
103
+
104
+
105
+ class Destination3Tuple(_NamedTuple): # .karney.py
106
+ '''3-Tuple C{(lat, lon, final)}, destination C{lat}, C{lon} in
107
+ C{degrees90} respectively C{degrees180} and C{final} bearing
108
+ in compass C{degrees360}.
109
+ '''
110
+ _Names_ = (_lat_, _lon_, _final_)
111
+ _Units_ = ( Lat, Lon, Bearing)
112
+
113
+
114
+ class Distance2Tuple(_NamedTuple): # .datum.py, .ellipsoidalBase.py
115
+ '''2-Tuple C{(distance, initial)}, C{distance} in C{meter} and
116
+ C{initial} bearing in compass C{degrees360}.
117
+ '''
118
+ _Names_ = (_distance_, _initial_)
119
+ _Units_ = ( Meter, Bearing)
120
+
121
+
122
+ class Distance3Tuple(_NamedTuple): # .ellipsoidalKarney.py, -Vincenty.py
123
+ '''3-Tuple C{(distance, initial, final)}, C{distance} in C{meter}
124
+ and C{initial} and C{final} bearing, both in compass C{degrees360}.
125
+ '''
126
+ _Names_ = (_distance_, _initial_, _final_)
127
+ _Units_ = ( Meter, Bearing, Bearing)
128
+
129
+
130
+ class Distance4Tuple(_NamedTuple): # .formy.py, .points.py
131
+ '''4-Tuple C{(distance2, delta_lat, delta_lon, unroll_lon2)} with
132
+ the distance in C{degrees squared}, the latitudinal C{delta_lat
133
+ = B{lat2} - B{lat1}}, the wrapped, unrolled and adjusted
134
+ longitudinal C{delta_lon = B{lon2} - B{lon1}} and C{unroll_lon2},
135
+ the unrolled or original B{C{lon2}}.
136
+
137
+ @note: Use Function L{pygeodesy.degrees2m} to convert C{degrees
138
+ squared} to C{meter} as M{degrees2m(sqrt(distance2), ...)}
139
+ or M{degrees2m(hypot(delta_lat, delta_lon), ...)}.
140
+ '''
141
+ _Names_ = ('distance2', 'delta_lat', 'delta_lon', 'unroll_lon2')
142
+ _Units_ = ( Degrees2, Degrees, Degrees, Degrees)
143
+
144
+
145
+ class EasNor2Tuple(_NamedTuple): # .css, .osgr, .ups, .utm, .utmupsBase
146
+ '''2-Tuple C{(easting, northing)}, both in C{meter}, conventionally.
147
+ '''
148
+ _Names_ = (_easting_, _northing_)
149
+ _Units_ = ( Easting, Northing)
150
+
151
+
152
+ class EasNor3Tuple(_NamedTuple): # .css.py, .lcc.py
153
+ '''3-Tuple C{(easting, northing, height)}, all in C{meter}, conventionally.
154
+ '''
155
+ _Names_ = (_easting_, _northing_, _height_)
156
+ _Units_ = ( Easting, Northing, Height)
157
+
158
+
159
+ class _Convergence(object):
160
+ '''(INTERNAL) DEPRECATED Property C{convergence}, use property C{gamma}.'''
161
+ @deprecated_property_RO
162
+ def convergence(self):
163
+ '''DEPRECATED, use property C{gamma}.
164
+ '''
165
+ return self.gamma # PYCHOK self[.]
166
+
167
+
168
+ class Forward4Tuple(_NamedTuple, _Convergence):
169
+ '''4-Tuple C{(easting, northing, gamma, scale)} in
170
+ C{meter}, C{meter}, meridian convergence C{gamma} at
171
+ point in C{degrees} and the C{scale} of projection
172
+ at point C{scalar}.
173
+ '''
174
+ _Names_ = (_easting_, _northing_, _gamma_, _scale_)
175
+ _Units_ = ( Easting, Northing, Degrees, Scalar)
176
+
177
+
178
+ class Intersection3Tuple(_NamedTuple): # .css.py, .lcc.py
179
+ '''3-Tuple C{(point, outside1, outside2)} of an intersection
180
+ C{point} and C{outside1}, the position of the C{point},
181
+ C{-1} if before the start, C{+1} if after the end and C{0}
182
+ if on or between the start and end point of the first line.
183
+ Similarly, C{outside2} is C{-2}, C{+2} or C{0} to indicate
184
+ the position of C{point} on the second line or path. If a
185
+ path was specified with an initial bearing instead of an
186
+ end point, C{outside1} and/or C{outside2} will be C{0} if
187
+ the intersection C{point} is on the start point or C{+1}
188
+ respectively C{+2} if the intersection C{point} is after
189
+ the start point, in the direction of the bearing.
190
+ '''
191
+ _Names_ = (_point_, _outside_ + _1_, _outside_ + _2_)
192
+ _Units_ = (_Pass, Int, Int)
193
+
194
+
195
+ class LatLon2Tuple(_NamedTuple):
196
+ '''2-Tuple C{(lat, lon)} in C{degrees90} and C{degrees180}.
197
+ '''
198
+ _Names_ = (_lat_, _lon_)
199
+ _Units_ = ( Lat, Lon)
200
+
201
+ def to3Tuple(self, height, **name):
202
+ '''Extend this L{LatLon2Tuple} to a L{LatLon3Tuple}.
203
+
204
+ @arg height: The height to add (C{scalar}).
205
+ @kwarg name: Optional name (C{str}), overriding this name.
206
+
207
+ @return: A L{LatLon3Tuple}C{(lat, lon, height)}.
208
+
209
+ @raise ValueError: Invalid B{C{height}}.
210
+ '''
211
+ return self._xtend(LatLon3Tuple, height, **name)
212
+
213
+ def to4Tuple(self, height, datum, **name):
214
+ '''Extend this L{LatLon2Tuple} to a L{LatLon4Tuple}.
215
+
216
+ @arg height: The height to add (C{scalar}).
217
+ @arg datum: The datum to add (C{Datum}).
218
+ @kwarg name: Optional name (C{str}), overriding this name.
219
+
220
+ @return: A L{LatLon4Tuple}C{(lat, lon, height, datum)}.
221
+
222
+ @raise TypeError: If B{C{datum}} not a C{Datum}.
223
+
224
+ @raise ValueError: Invalid B{C{height}}.
225
+ '''
226
+ return self.to3Tuple(height).to4Tuple(datum, **name)
227
+
228
+
229
+ class LatLon3Tuple(_NamedTuple):
230
+ '''3-Tuple C{(lat, lon, height)} in C{degrees90}, C{degrees180}
231
+ and C{meter}, conventionally.
232
+ '''
233
+ _Names_ = (_lat_, _lon_, _height_)
234
+ _Units_ = ( Lat, Lon, Height)
235
+
236
+ def to4Tuple(self, datum, **name):
237
+ '''Extend this L{LatLon3Tuple} to a L{LatLon4Tuple}.
238
+
239
+ @arg datum: The datum to add (C{Datum}).
240
+ @kwarg name: Optional name (C{str}), overriding this name.
241
+
242
+ @return: A L{LatLon4Tuple}C{(lat, lon, height, datum)}.
243
+
244
+ @raise TypeError: If B{C{datum}} not a C{Datum}.
245
+ '''
246
+ _xinstanceof(_MODS.datums.Datum, datum=datum)
247
+ return self._xtend(LatLon4Tuple, datum, **name)
248
+
249
+
250
+ class LatLon4Tuple(LatLon3Tuple): # .cartesianBase, .css, .ecef, .lcc
251
+ '''4-Tuple C{(lat, lon, height, datum)} in C{degrees90},
252
+ C{degrees180}, C{meter} and L{Datum}.
253
+ '''
254
+ _Names_ = (_lat_, _lon_, _height_, _datum_)
255
+ _Units_ = ( Lat, Lon, Height, _Pass)
256
+
257
+
258
+ def _LL4Tuple(lat, lon, height, datum, LatLon, LatLon_kwds, inst=None,
259
+ iteration=None, name=NN):
260
+ '''(INTERNAL) Return a L{LatLon4Tuple} or a B{C{LatLon}} instance.
261
+ '''
262
+ if LatLon is None: # ignore LatLon_kwds
263
+ r = LatLon4Tuple(lat, lon, height, datum, name=name)
264
+ else:
265
+ kwds = {} if inst is None else _xkwds_not(None,
266
+ # datum=_xattr(inst, datum=None),
267
+ epoch=_xattr(inst, epoch=None),
268
+ reframe=_xattr(inst, reframe=None)) # PYCHOK indent
269
+ kwds.update(datum=datum, height=height, name=name)
270
+ if LatLon_kwds:
271
+ kwds.update(LatLon_kwds)
272
+ r = LatLon(lat, lon, **kwds)
273
+ if iteration is not None: # like .named._namedTuple.__new__
274
+ r._iteration = iteration
275
+ return r
276
+
277
+
278
+ class LatLonDatum3Tuple(_NamedTuple): # .lcc.py, .osgr.py
279
+ '''3-Tuple C{(lat, lon, datum)} in C{degrees90}, C{degrees180}
280
+ and L{Datum}.
281
+ '''
282
+ _Names_ = (_lat_, _lon_, _datum_)
283
+ _Units_ = ( Lat, Lon, _Pass)
284
+
285
+
286
+ class LatLonDatum5Tuple(LatLonDatum3Tuple, _Convergence): # .ups.py, .utm.py, .utmupsBase.py
287
+ '''5-Tuple C{(lat, lon, datum, gamma, scale)} in C{degrees90},
288
+ C{degrees180}, L{Datum}, C{degrees} and C{float}.
289
+ '''
290
+ _Names_ = LatLonDatum3Tuple._Names_ + (_gamma_, _scale_)
291
+ _Units_ = LatLonDatum3Tuple._Units_ + ( Degrees, Scalar)
292
+
293
+
294
+ class LatLonPrec3Tuple(_NamedTuple): # .gars.py, .wgrs.py
295
+ '''3-Tuple C{(lat, lon, precision)} in C{degrees}, C{degrees}
296
+ and C{int}.
297
+ '''
298
+ _Names_ = (_lat_, _lon_, _precision_)
299
+ _Units_ = ( Lat, Lon, Precision_)
300
+
301
+ def to5Tuple(self, height, radius, **name):
302
+ '''Extend this L{LatLonPrec3Tuple} to a L{LatLonPrec5Tuple}.
303
+
304
+ @arg height: The height to add (C{float} or C{None}).
305
+ @arg radius: The radius to add (C{float} or C{None}).
306
+ @kwarg name: Optional name (C{str}), overriding this name.
307
+
308
+ @return: A L{LatLonPrec5Tuple}C{(lat, lon, precision,
309
+ height, radius)}.
310
+ '''
311
+ return self._xtend(LatLonPrec5Tuple, height, radius, **name)
312
+
313
+
314
+ class LatLonPrec5Tuple(LatLonPrec3Tuple): # .wgrs.py
315
+ '''5-Tuple C{(lat, lon, precision, height, radius)} in C{degrees},
316
+ C{degrees}, C{int} and C{height} or C{radius} in C{meter} (or
317
+ C{None} if missing).
318
+ '''
319
+ _Names_ = LatLonPrec3Tuple._Names_ + (_height_, _radius_)
320
+ _Units_ = LatLonPrec3Tuple._Units_ + ( Height, Radius)
321
+
322
+
323
+ class NearestOn2Tuple(_NamedTuple): # .ellipsoidalBaseDI
324
+ '''2-Tuple C{(closest, fraction)} of the C{closest} point
325
+ on and C{fraction} along a line (segment) between two
326
+ points. The C{fraction} is C{0} if the closest point
327
+ is the first or C{1} the second of the two points.
328
+ Negative C{fraction}s indicate the closest point is
329
+ C{before} the first point. For C{fraction > 1.0}
330
+ the closest point is after the second point.
331
+ '''
332
+ _Names_ = (_closest_, _fraction_)
333
+ _Units_ = (_Pass, _Pass)
334
+
335
+
336
+ class NearestOn3Tuple(_NamedTuple): # .points.py, .sphericalTrigonometry
337
+ '''3-Tuple C{(closest, distance, angle)} of the C{closest}
338
+ point on the polygon, either a C{LatLon} instance or a
339
+ L{LatLon3Tuple}C{(lat, lon, height)} and the C{distance}
340
+ and C{angle} to the C{closest} point are in C{meter}
341
+ respectively compass C{degrees360}.
342
+ '''
343
+ _Names_ = (_closest_, _distance_, _angle_)
344
+ _Units_ = (_Pass, Meter, Degrees)
345
+
346
+
347
+ # NearestOn4Tuple DEPRECATED, see .deprecated.classes.NearestOn4Tuple
348
+
349
+
350
+ class NearestOn5Tuple(_NamedTuple):
351
+ '''5-Tuple C{(lat, lon, distance, angle, height)} all in C{degrees},
352
+ except C{height}. The C{distance} is the L{pygeodesy.equirectangular}
353
+ distance between the closest and the reference B{C{point}} in C{degrees}.
354
+ The C{angle} from the reference B{C{point}} to the closest point is in
355
+ compass C{degrees360}, see function L{pygeodesy.compassAngle}. The
356
+ C{height} is the (interpolated) height at the closest point in C{meter}
357
+ or C{0}.
358
+ '''
359
+ _Names_ = (_lat_, _lon_, _distance_, _angle_, _height_)
360
+ _Units_ = ( Lat, Lon, Degrees, Degrees, Meter)
361
+
362
+
363
+ class NearestOn6Tuple(_NamedTuple): # .latlonBase.py, .vector3d.py
364
+ '''6-Tuple C{(closest, distance, fi, j, start, end)} with the C{closest}
365
+ point, the C{distance} in C{meter}, conventionally and the C{start}
366
+ and C{end} point of the path or polygon edge. Fractional index C{fi}
367
+ (an L{FIx} instance) and index C{j} indicate the path or polygon edge
368
+ and the fraction along that edge with the C{closest} point. The
369
+ C{start} and C{end} points may differ from the given path or polygon
370
+ points at indices C{fi} respectively C{j}, when unrolled (C{wrap} is
371
+ C{True}). Also, the C{start} and/or C{end} point may be the same
372
+ instance as the C{closest} point, for example when the very first
373
+ path or polygon point is the nearest.
374
+ '''
375
+ _Names_ = (_closest_, _distance_, _fi_, _j_, _start_, _end_)
376
+ _Units_ = (_Pass, Meter, FIx, Number_, _Pass , _Pass)
377
+
378
+
379
+ class NearestOn8Tuple(_NamedTuple): # .ellipsoidalBaseDI
380
+ '''8-Tuple C{(closest, distance, fi, j, start, end, initial, final)},
381
+ like L{NearestOn6Tuple} but extended with the C{initial} and the
382
+ C{final} bearing at the reference respectively the C{closest}
383
+ point, both in compass C{degrees}.
384
+ '''
385
+ _Names_ = NearestOn6Tuple._Names_ + Distance3Tuple._Names_[-2:]
386
+ _Units_ = NearestOn6Tuple._Units_ + Distance3Tuple._Units_[-2:]
387
+
388
+
389
+ class PhiLam2Tuple(_NamedTuple): # .frechet, .hausdorff, .latlonBase, .points, .vector3d
390
+ '''2-Tuple C{(phi, lam)} with latitude C{phi} in C{radians[PI_2]}
391
+ and longitude C{lam} in C{radians[PI]}.
392
+
393
+ @note: Using C{phi/lambda} for lat-/longitude in C{radians}
394
+ follows Chris Veness' U{convention
395
+ <https://www.Movable-Type.co.UK/scripts/latlong.html>}.
396
+ '''
397
+ _Names_ = (_phi_, _lam_)
398
+ _Units_ = ( Phi, Lam)
399
+
400
+ def to3Tuple(self, height, **name):
401
+ '''Extend this L{PhiLam2Tuple} to a L{PhiLam3Tuple}.
402
+
403
+ @arg height: The height to add (C{scalar}).
404
+ @kwarg name: Optional name (C{str}), overriding this name.
405
+
406
+ @return: A L{PhiLam3Tuple}C{(phi, lam, height)}.
407
+
408
+ @raise ValueError: Invalid B{C{height}}.
409
+ '''
410
+ return self._xtend(PhiLam3Tuple, height, **name)
411
+
412
+ def to4Tuple(self, height, datum):
413
+ '''Extend this L{PhiLam2Tuple} to a L{PhiLam4Tuple}.
414
+
415
+ @arg height: The height to add (C{scalar}).
416
+ @arg datum: The datum to add (C{Datum}).
417
+
418
+ @return: A L{PhiLam4Tuple}C{(phi, lam, height, datum)}.
419
+
420
+ @raise TypeError: If B{C{datum}} not a C{Datum}.
421
+
422
+ @raise ValueError: Invalid B{C{height}}.
423
+ '''
424
+ return self.to3Tuple(height).to4Tuple(datum)
425
+
426
+
427
+ class PhiLam3Tuple(_NamedTuple): # .nvector.py, extends -2Tuple
428
+ '''3-Tuple C{(phi, lam, height)} with latitude C{phi} in
429
+ C{radians[PI_2]}, longitude C{lam} in C{radians[PI]} and
430
+ C{height} in C{meter}.
431
+
432
+ @note: Using C{phi/lambda} for lat-/longitude in C{radians}
433
+ follows Chris Veness' U{convention
434
+ <https://www.Movable-Type.co.UK/scripts/latlong.html>}.
435
+ '''
436
+ _Names_ = (_phi_, _lam_, _height_)
437
+ _Units_ = ( Phi, Lam, Height)
438
+
439
+ def to4Tuple(self, datum, **name):
440
+ '''Extend this L{PhiLam3Tuple} to a L{PhiLam4Tuple}.
441
+
442
+ @arg datum: The datum to add (C{Datum}).
443
+ @kwarg name: Optional name (C{str}), overriding this name.
444
+
445
+ @return: A L{PhiLam4Tuple}C{(phi, lam, height, datum)}.
446
+
447
+ @raise TypeError: If B{C{datum}} not a C{Datum}.
448
+ '''
449
+ _xinstanceof(_MODS.datums.Datum, datum=datum)
450
+ return self._xtend(PhiLam4Tuple, datum, **name)
451
+
452
+
453
+ class PhiLam4Tuple(_NamedTuple): # extends -3Tuple
454
+ '''4-Tuple C{(phi, lam, height, datum)} with latitude C{phi} in
455
+ C{radians[PI_2]}, longitude C{lam} in C{radians[PI]}, C{height}
456
+ in C{meter} and L{Datum}.
457
+
458
+ @note: Using C{phi/lambda} for lat-/longitude in C{radians}
459
+ follows Chris Veness' U{convention
460
+ <https://www.Movable-Type.co.UK/scripts/latlong.html>}.
461
+ '''
462
+ _Names_ = (_phi_, _lam_, _height_, _datum_)
463
+ _Units_ = ( Phi, Lam, Height, _Pass)
464
+
465
+
466
+ class Point3Tuple(_NamedTuple):
467
+ '''3-Tuple C{(x, y, ll)} in C{meter}, C{meter} and C{LatLon}.
468
+ '''
469
+ _Names_ = (_x_, _y_, _elel_)
470
+ _Units_ = ( Meter, Meter, _Pass)
471
+
472
+
473
+ class Points2Tuple(_NamedTuple): # .formy, .latlonBase
474
+ '''2-Tuple C{(number, points)} with the C{number} of points
475
+ and -possible reduced- C{list} or C{tuple} of C{points}.
476
+ '''
477
+ _Names_ = (_number_, _points_)
478
+ _Units_ = ( Number_, _Pass)
479
+
480
+
481
+ class Reverse4Tuple(_NamedTuple, _Convergence):
482
+ '''4-Tuple C{(lat, lon, gamma, scale)} with C{lat}- and
483
+ C{lon}gitude in C{degrees}, meridian convergence C{gamma}
484
+ at point in C{degrees} and the C{scale} of projection at
485
+ point C{scalar}.
486
+ '''
487
+ _Names_ = (_lat_, _lon_, _gamma_, _scale_)
488
+ _Units_ = ( Lat, Lon, Degrees, Scalar)
489
+
490
+
491
+ class Triangle7Tuple(_NamedTuple):
492
+ '''7-Tuple C{(A, a, B, b, C, c, area)} with interior angles C{A},
493
+ C{B} and C{C} in C{degrees}, spherical sides C{a}, C{b} and C{c}
494
+ in C{meter} conventionally and the C{area} of a (spherical)
495
+ triangle in I{square} C{meter} conventionally.
496
+ '''
497
+ _Names_ = (_A_, _a_, _B_, _b_, _C_, _c_, _area_)
498
+ _Units_ = ( Degrees, Meter, Degrees, Meter, Degrees, Meter, Meter2)
499
+
500
+
501
+ class Triangle8Tuple(_NamedTuple):
502
+ '''8-Tuple C{(A, a, B, b, C, c, D, E)} with interior angles C{A},
503
+ C{B} and C{C}, spherical sides C{a}, C{b} and C{c}, the I{spherical
504
+ deficit} C{D} and the I{spherical excess} C{E} of a (spherical)
505
+ triangle, all in C{radians}.
506
+ '''
507
+ _Names_ = (_A_, _a_, _B_, _b_, _C_, _c_, _D_, _E_)
508
+ _Units_ = ( Radians, Radians, Radians, Radians, Radians, Radians, Radians, Radians)
509
+
510
+
511
+ class Trilaterate5Tuple(_NamedTuple): # .latlonBase, .nvector
512
+ '''5-Tuple C{(min, minPoint, max, maxPoint, n)} with C{min} and C{max}
513
+ in C{meter}, the corresponding trilaterated C{minPoint} and C{maxPoint}
514
+ as C{LatLon} and the number C{n}. For area overlap, C{min} and C{max}
515
+ are the smallest respectively largest overlap found. For perimeter
516
+ intersection, C{min} and C{max} represent the closest respectively
517
+ farthest intersection margin. Count C{n} is the total number of
518
+ trilaterated overlaps or intersections found, C{0, 1, 2...6} with
519
+ C{0} meaning concentric.
520
+
521
+ @see: The C{ellipsoidalKarney-}, C{ellipsoidalVincenty-} and
522
+ C{sphericalTrigonometry.LatLon.trilaterate5} method for further
523
+ details on corner cases, like concentric or single trilaterated
524
+ results.
525
+ '''
526
+ _Names_ = (min.__name__, 'minPoint', max.__name__, 'maxPoint', _n_)
527
+ _Units_ = (Meter, _Pass, Meter, _Pass, Number_)
528
+
529
+
530
+ class UtmUps2Tuple(_NamedTuple): # .epsg.py
531
+ '''2-Tuple C{(zone, hemipole)} as C{int} and C{str}, where
532
+ C{zone} is C{1..60} for UTM or C{0} for UPS and C{hemipole}
533
+ C{'N'|'S'} is the UTM hemisphere or the UPS pole.
534
+ '''
535
+ _Names_ = (_zone_, _hemipole_)
536
+ _Units_ = ( Number_, Str)
537
+
538
+
539
+ class UtmUps5Tuple(_NamedTuple): # .mgrs.py, .ups.py, .utm.py, .utmups.py
540
+ '''5-Tuple C{(zone, hemipole, easting, northing, band)} as C{int},
541
+ C{str}, C{meter}, C{meter} and C{band} letter, where C{zone} is
542
+ C{1..60} for UTM or C{0} for UPS, C{hemipole} C{'N'|'S'} is the UTM
543
+ hemisphere or the UPS pole and C{band} is C{""} or the I{longitudinal}
544
+ UTM band C{'C'|'D'|..|'W'|'X'} or I{polar} UPS band C{'A'|'B'|'Y'|'Z'}.
545
+ '''
546
+ _Names_ = (_zone_, _hemipole_, _easting_, _northing_, _band_)
547
+ _Units_ = ( Number_, Str, Easting, Northing, Band)
548
+
549
+ def __new__(cls, z, h, e, n, B, Error=None, name=NN):
550
+ if Error is not None:
551
+ e = Easting( e, Error=Error)
552
+ n = Northing(n, Error=Error)
553
+ return _NamedTuple.__new__(cls, z, h, e, n, B, name=name)
554
+
555
+
556
+ class UtmUps8Tuple(_NamedTuple, _Convergence): # .ups, .utm, .utmups
557
+ '''8-Tuple C{(zone, hemipole, easting, northing, band, datum,
558
+ gamma, scale)} as C{int}, C{str}, C{meter}, C{meter}, C{band}
559
+ letter, C{Datum}, C{degrees} and C{scalar}, where C{zone} is
560
+ C{1..60} for UTM or C{0} for UPS, C{hemipole} C{'N'|'S'} is
561
+ the UTM hemisphere or the UPS pole and C{band} is C{""} or
562
+ the I{longitudinal} UTM band C{'C'|'D'|..|'W'|'X'} or
563
+ I{polar} UPS band C{'A'|'B'|'Y'|'Z'}.
564
+ '''
565
+ _Names_ = (_zone_, _hemipole_, _easting_, _northing_,
566
+ _band_, _datum_, _gamma_, _scale_)
567
+ _Units_ = ( Number_, Str, Easting, Northing,
568
+ Band, _Pass, Degrees, Scalar)
569
+
570
+ def __new__(cls, z, h, e, n, B, d, g, s, Error=None, name=NN): # PYCHOK 11 args
571
+ if Error is not None:
572
+ e = Easting( e, Error=Error)
573
+ n = Northing(n, Error=Error)
574
+ g = Degrees(gamma=g, Error=Error)
575
+ s = Scalar(scale=s, Error=Error)
576
+ return _NamedTuple.__new__(cls, z, h, e, n, B, d, g, s, name=name)
577
+
578
+
579
+ class UtmUpsLatLon5Tuple(_NamedTuple): # .ups.py, .utm.py, .utmups.py
580
+ '''5-Tuple C{(zone, band, hemipole, lat, lon)} as C{int},
581
+ C{str}, C{str}, C{degrees90} and C{degrees180}, where
582
+ C{zone} is C{1..60} for UTM or C{0} for UPS, C{band} is
583
+ C{""} or the I{longitudinal} UTM band C{'C'|'D'|..|'W'|'X'}
584
+ or I{polar} UPS band C{'A'|'B'|'Y'|'Z'} and C{hemipole}
585
+ C{'N'|'S'} is the UTM hemisphere or the UPS pole.
586
+ '''
587
+ _Names_ = (_zone_, _band_, _hemipole_, _lat_, _lon_)
588
+ _Units_ = ( Number_, Band, Str, Lat, Lon)
589
+
590
+ def __new__(cls, z, B, h, lat, lon, Error=None, name=NN):
591
+ if Error is not None:
592
+ lat = Lat(lat, Error=Error)
593
+ lon = Lon(lon, Error=Error)
594
+ return _NamedTuple.__new__(cls, z, B, h, lat, lon, name=name)
595
+
596
+
597
+ class Vector2Tuple(_NamedTuple):
598
+ '''2-Tuple C{(x, y)} of (geocentric) components, each in
599
+ C{meter} or the same C{units}.
600
+ '''
601
+ _Names_ = (_x_, _y_)
602
+ _Units_ = ( Scalar, Scalar)
603
+
604
+ def to3Tuple(self, z=INT0, **name):
605
+ '''Extend this L{Vector2Tuple} to a L{Vector3Tuple}.
606
+
607
+ @kwarg z: The Z component add (C{scalar}).
608
+ @kwarg name: Optional name (C{str}), overriding this name.
609
+
610
+ @return: A L{Vector3Tuple}C{(x, y, z)}.
611
+
612
+ @raise ValueError: Invalid B{C{z}}.
613
+ '''
614
+ return self._xtend(Vector3Tuple, z, **name)
615
+
616
+
617
+ class Vector3Tuple(_NamedTuple):
618
+ '''3-Tuple C{(x, y, z)} of (geocentric) components, all in
619
+ C{meter} or the same C{units}.
620
+ '''
621
+ _Names_ = (_x_, _y_, _z_)
622
+ _Units_ = ( Scalar, Scalar, Scalar)
623
+
624
+ def to4Tuple(self, h=INT0, **name):
625
+ '''Extend this L{Vector3Tuple} to a L{Vector4Tuple}.
626
+
627
+ @arg h: The height to add (C{scalar}).
628
+ @kwarg name: Optional name (C{str}), overriding this name.
629
+
630
+ @return: A L{Vector4Tuple}C{(x, y, z, h)}.
631
+
632
+ @raise ValueError: Invalid B{C{h}}.
633
+ '''
634
+ return self._xtend(Vector4Tuple, h, **name)
635
+
636
+ @property_RO
637
+ def xyz(self):
638
+ '''Get X, Y and Z components (C{Vector3Tuple}).
639
+ '''
640
+ return self
641
+
642
+
643
+ class Vector4Tuple(_NamedTuple): # .nvector.py
644
+ '''4-Tuple C{(x, y, z, h)} of (geocentric) components, all
645
+ in C{meter} or the same C{units}.
646
+ '''
647
+ _Names_ = (_x_, _y_, _z_, _h_)
648
+ _Units_ = ( Scalar, Scalar, Scalar, Height)
649
+
650
+ def to3Tuple(self):
651
+ '''Reduce this L{Vector4Tuple} to a L{Vector3Tuple}.
652
+
653
+ @return: A L{Vector3Tuple}C{(x, y, z)}.
654
+ '''
655
+ return self.xyz
656
+
657
+ @property_RO
658
+ def xyz(self):
659
+ '''Get X, Y and Z components (L{Vector3Tuple}).
660
+ '''
661
+ return Vector3Tuple(*self[:3])
662
+
663
+ # **) MIT License
664
+ #
665
+ # Copyright (C) 2016-2024 -- mrJean1 at Gmail -- All Rights Reserved.
666
+ #
667
+ # Permission is hereby granted, free of charge, to any person obtaining a
668
+ # copy of this software and associated documentation files (the "Software"),
669
+ # to deal in the Software without restriction, including without limitation
670
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
671
+ # and/or sell copies of the Software, and to permit persons to whom the
672
+ # Software is furnished to do so, subject to the following conditions:
673
+ #
674
+ # The above copyright notice and this permission notice shall be included
675
+ # in all copies or substantial portions of the Software.
676
+ #
677
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
678
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
679
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
680
+ # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
681
+ # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
682
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
683
+ # OTHER DEALINGS IN THE SOFTWARE.