pygeodesy 24.5.15__py2.py3-none-any.whl → 24.6.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/METADATA +6 -5
- PyGeodesy-24.6.1.dist-info/RECORD +116 -0
- pygeodesy/__init__.py +4 -4
- pygeodesy/albers.py +41 -41
- pygeodesy/auxilats/__init__.py +1 -1
- pygeodesy/auxilats/__main__.py +2 -2
- pygeodesy/auxilats/auxAngle.py +32 -31
- pygeodesy/auxilats/auxLat.py +80 -51
- pygeodesy/azimuthal.py +123 -124
- pygeodesy/basics.py +46 -10
- pygeodesy/booleans.py +13 -14
- pygeodesy/cartesianBase.py +25 -23
- pygeodesy/clipy.py +3 -3
- pygeodesy/constants.py +3 -3
- pygeodesy/css.py +50 -42
- pygeodesy/datums.py +42 -41
- pygeodesy/deprecated/functions.py +9 -3
- pygeodesy/dms.py +6 -6
- pygeodesy/ecef.py +41 -41
- pygeodesy/ellipsoidalBase.py +41 -41
- pygeodesy/ellipsoidalBaseDI.py +3 -4
- pygeodesy/ellipsoidalGeodSolve.py +2 -2
- pygeodesy/ellipsoidalKarney.py +3 -3
- pygeodesy/ellipsoidalNvector.py +11 -12
- pygeodesy/ellipsoids.py +45 -38
- pygeodesy/elliptic.py +3 -4
- pygeodesy/epsg.py +4 -3
- pygeodesy/errors.py +52 -20
- pygeodesy/etm.py +68 -65
- pygeodesy/fmath.py +44 -49
- pygeodesy/formy.py +129 -115
- pygeodesy/frechet.py +118 -103
- pygeodesy/fstats.py +21 -14
- pygeodesy/fsums.py +124 -80
- pygeodesy/gars.py +10 -9
- pygeodesy/geodesicw.py +19 -17
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +2 -2
- pygeodesy/geodesicx/gx.py +39 -33
- pygeodesy/geodesicx/gxarea.py +12 -9
- pygeodesy/geodesicx/gxbases.py +3 -4
- pygeodesy/geodesicx/gxline.py +6 -8
- pygeodesy/geodsolve.py +29 -28
- pygeodesy/geohash.py +60 -57
- pygeodesy/geoids.py +34 -32
- pygeodesy/hausdorff.py +114 -101
- pygeodesy/heights.py +137 -130
- pygeodesy/internals.py +16 -11
- pygeodesy/interns.py +3 -6
- pygeodesy/iters.py +19 -17
- pygeodesy/karney.py +21 -17
- pygeodesy/ktm.py +25 -18
- pygeodesy/latlonBase.py +12 -11
- pygeodesy/lazily.py +6 -6
- pygeodesy/lcc.py +24 -25
- pygeodesy/ltp.py +143 -113
- pygeodesy/ltpTuples.py +207 -150
- pygeodesy/mgrs.py +26 -26
- pygeodesy/named.py +172 -90
- pygeodesy/namedTuples.py +33 -25
- pygeodesy/nvectorBase.py +8 -8
- pygeodesy/osgr.py +40 -48
- pygeodesy/points.py +18 -18
- pygeodesy/props.py +29 -16
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +13 -15
- pygeodesy/rhumb/bases.py +12 -5
- pygeodesy/rhumb/ekx.py +24 -18
- pygeodesy/rhumb/solve.py +13 -10
- pygeodesy/simplify.py +16 -16
- pygeodesy/solveBase.py +18 -18
- pygeodesy/sphericalBase.py +17 -21
- pygeodesy/sphericalTrigonometry.py +21 -21
- pygeodesy/streprs.py +5 -5
- pygeodesy/trf.py +13 -11
- pygeodesy/triaxials.py +68 -64
- pygeodesy/units.py +35 -35
- pygeodesy/unitsBase.py +24 -11
- pygeodesy/ups.py +66 -70
- pygeodesy/utily.py +3 -3
- pygeodesy/utm.py +183 -187
- pygeodesy/utmups.py +38 -38
- pygeodesy/utmupsBase.py +104 -106
- pygeodesy/vector2d.py +6 -7
- pygeodesy/vector3d.py +16 -17
- pygeodesy/vector3dBase.py +4 -5
- pygeodesy/webmercator.py +43 -51
- PyGeodesy-24.5.15.dist-info/RECORD +0 -116
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/WHEEL +0 -0
- {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.6.1.dist-info}/top_level.txt +0 -0
pygeodesy/formy.py
CHANGED
|
@@ -8,7 +8,7 @@ from __future__ import division as _; del _ # PYCHOK semicolon
|
|
|
8
8
|
|
|
9
9
|
# from pygeodesy.cartesianBase import CartesianBase # _MODS
|
|
10
10
|
from pygeodesy.constants import EPS, EPS0, EPS1, PI, PI2, PI3, PI_2, R_M, \
|
|
11
|
-
|
|
11
|
+
_0_0s, float0_, isnon0, remainder, _umod_PI2, \
|
|
12
12
|
_0_0, _0_125, _0_25, _0_5, _1_0, _2_0, _4_0, \
|
|
13
13
|
_32_0, _90_0, _180_0, _360_0
|
|
14
14
|
from pygeodesy.datums import Datum, Ellipsoid, _ellipsoidal_datum, \
|
|
@@ -16,16 +16,18 @@ from pygeodesy.datums import Datum, Ellipsoid, _ellipsoidal_datum, \
|
|
|
16
16
|
# from pygeodesy.ellipsoids import Ellipsoid, _EWGS84 # from .datums
|
|
17
17
|
from pygeodesy.errors import IntersectionError, LimitError, limiterrors, \
|
|
18
18
|
_TypeError, _ValueError, _xattr, _xError, \
|
|
19
|
-
_xkwds, _xkwds_pop2
|
|
19
|
+
_xcallable,_xkwds, _xkwds_pop2
|
|
20
20
|
from pygeodesy.fmath import euclid, hypot, hypot2, sqrt0
|
|
21
|
-
from pygeodesy.fsums import fsumf_
|
|
22
|
-
from pygeodesy.
|
|
21
|
+
from pygeodesy.fsums import fsumf_, Fmt, unstr
|
|
22
|
+
# from pygeodesy.internals import _dunder_nameof # from .named
|
|
23
|
+
from pygeodesy.interns import _delta_, _distant_, _inside_, _SPACE_, _too_
|
|
23
24
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
24
|
-
from pygeodesy.named import _NamedTuple, _xnamed,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# from pygeodesy.
|
|
25
|
+
from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed, \
|
|
26
|
+
_dunder_nameof
|
|
27
|
+
from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
|
|
28
|
+
Intersection3Tuple, PhiLam2Tuple, Vector3Tuple
|
|
29
|
+
# from pygeodesy.streprs import Fmt, unstr # from .fsums
|
|
30
|
+
# from pygeodesy.triaxials import _hartzell3 # _MODS
|
|
29
31
|
from pygeodesy.units import _isHeight, _isRadius, Bearing, Degrees_, Distance, \
|
|
30
32
|
Distance_, Height, Lam_, Lat, Lon, Meter_, Phi_, \
|
|
31
33
|
Radians, Radians_, Radius, Radius_, Scalar, _100km
|
|
@@ -40,7 +42,7 @@ from contextlib import contextmanager
|
|
|
40
42
|
from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
|
|
41
43
|
|
|
42
44
|
__all__ = _ALL_LAZY.formy
|
|
43
|
-
__version__ = '24.
|
|
45
|
+
__version__ = '24.05.28'
|
|
44
46
|
|
|
45
47
|
_RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
|
|
46
48
|
_ratio_ = 'ratio'
|
|
@@ -59,36 +61,36 @@ def _anti2(a, b, n_2, n, n2):
|
|
|
59
61
|
return float0_(r, b)
|
|
60
62
|
|
|
61
63
|
|
|
62
|
-
def antipode(lat, lon, name
|
|
64
|
+
def antipode(lat, lon, **name):
|
|
63
65
|
'''Return the antipode, the point diametrically opposite
|
|
64
66
|
to a given point in C{degrees}.
|
|
65
67
|
|
|
66
68
|
@arg lat: Latitude (C{degrees}).
|
|
67
69
|
@arg lon: Longitude (C{degrees}).
|
|
68
|
-
@kwarg name: Optional name (C{str}).
|
|
70
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
69
71
|
|
|
70
72
|
@return: A L{LatLon2Tuple}C{(lat, lon)}.
|
|
71
73
|
|
|
72
74
|
@see: Functions L{antipode_} and L{normal} and U{Geosphere
|
|
73
75
|
<https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
|
|
74
76
|
'''
|
|
75
|
-
return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), name
|
|
77
|
+
return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), **name)
|
|
76
78
|
|
|
77
79
|
|
|
78
|
-
def antipode_(phi, lam, name
|
|
80
|
+
def antipode_(phi, lam, **name):
|
|
79
81
|
'''Return the antipode, the point diametrically opposite
|
|
80
82
|
to a given point in C{radians}.
|
|
81
83
|
|
|
82
84
|
@arg phi: Latitude (C{radians}).
|
|
83
85
|
@arg lam: Longitude (C{radians}).
|
|
84
|
-
@kwarg name: Optional name (C{str}).
|
|
86
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
85
87
|
|
|
86
88
|
@return: A L{PhiLam2Tuple}C{(phi, lam)}.
|
|
87
89
|
|
|
88
90
|
@see: Functions L{antipode} and L{normal_} and U{Geosphere
|
|
89
91
|
<https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
|
|
90
92
|
'''
|
|
91
|
-
return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), name
|
|
93
|
+
return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), **name)
|
|
92
94
|
|
|
93
95
|
|
|
94
96
|
def bearing(lat1, lon1, lat2, lon2, **final_wrap):
|
|
@@ -118,16 +120,17 @@ def bearing_(phi1, lam1, phi2, lam2, final=False, wrap=False):
|
|
|
118
120
|
@arg lam1: Start longitude (C{radians}).
|
|
119
121
|
@arg phi2: End latitude (C{radians}).
|
|
120
122
|
@arg lam2: End longitude (C{radians}).
|
|
121
|
-
@kwarg final:
|
|
122
|
-
|
|
123
|
-
|
|
123
|
+
@kwarg final: If C{True}, return the final, otherwise the initial
|
|
124
|
+
bearing (C{bool}).
|
|
125
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}}
|
|
126
|
+
and B{C{lam2}} (C{bool}).
|
|
124
127
|
|
|
125
|
-
@return: Initial or final bearing (compass C{radiansPI2}) or zero if
|
|
126
|
-
and end point coincide.
|
|
128
|
+
@return: Initial or final bearing (compass C{radiansPI2}) or zero if
|
|
129
|
+
start and end point coincide.
|
|
127
130
|
|
|
128
|
-
@see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>},
|
|
129
|
-
between two points<https://www.EdWilliams.org/avform147.htm#Crs>}
|
|
130
|
-
U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
|
|
131
|
+
@see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>},
|
|
132
|
+
U{Course between two points<https://www.EdWilliams.org/avform147.htm#Crs>}
|
|
133
|
+
and U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
|
|
131
134
|
https://MathForum.org/library/drmath/view/55417.html>}.
|
|
132
135
|
'''
|
|
133
136
|
db, phi2, lam2 = _Wrap.philam3(lam1, phi2, lam2, wrap)
|
|
@@ -154,7 +157,7 @@ def _bearingTo2(p1, p2, wrap=False): # for points.ispolar, sphericalTrigonometr
|
|
|
154
157
|
t = p1.philam + p2.philam
|
|
155
158
|
return Bearing2Tuple(degrees(bearing_(*t, final=False, wrap=wrap)),
|
|
156
159
|
degrees(bearing_(*t, final=True, wrap=wrap)),
|
|
157
|
-
|
|
160
|
+
name__=_bearingTo2)
|
|
158
161
|
|
|
159
162
|
|
|
160
163
|
def compassAngle(lat1, lon1, lat2, lon2, adjust=True, wrap=False):
|
|
@@ -229,8 +232,8 @@ def cosineAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
|
|
|
229
232
|
@raise TypeError: Invalid B{C{datum}}.
|
|
230
233
|
|
|
231
234
|
@see: Functions L{cosineAndoyerLambert}, L{cosineForsytheAndoyerLambert_},
|
|
232
|
-
L{cosineLaw_}, L{
|
|
233
|
-
L{
|
|
235
|
+
L{cosineLaw_}, L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
|
|
236
|
+
L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
|
|
234
237
|
<https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/Distance/
|
|
235
238
|
AndoyerLambert.php>}.
|
|
236
239
|
'''
|
|
@@ -295,8 +298,8 @@ def cosineForsytheAndoyerLambert_(phi2, phi1, lam21, datum=_WGS84):
|
|
|
295
298
|
@raise TypeError: Invalid B{C{datum}}.
|
|
296
299
|
|
|
297
300
|
@see: Functions L{cosineForsytheAndoyerLambert}, L{cosineAndoyerLambert_},
|
|
298
|
-
L{cosineLaw_}, L{
|
|
299
|
-
L{
|
|
301
|
+
L{cosineLaw_}, L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
|
|
302
|
+
L{haversine_}, L{thomas_} and L{vincentys_} and U{Geodesy-PHP
|
|
300
303
|
<https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
|
|
301
304
|
Distance/ForsytheCorrection.php>}.
|
|
302
305
|
'''
|
|
@@ -363,9 +366,9 @@ def cosineLaw_(phi2, phi1, lam21):
|
|
|
363
366
|
@return: Angular distance (C{radians}).
|
|
364
367
|
|
|
365
368
|
@see: Functions L{cosineLaw}, L{cosineAndoyerLambert_},
|
|
366
|
-
L{cosineForsytheAndoyerLambert_},
|
|
367
|
-
L{
|
|
368
|
-
L{
|
|
369
|
+
L{cosineForsytheAndoyerLambert_}, L{euclidean_},
|
|
370
|
+
L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
|
|
371
|
+
L{thomas_} and L{vincentys_}.
|
|
369
372
|
|
|
370
373
|
@note: See note at function L{vincentys_}.
|
|
371
374
|
'''
|
|
@@ -416,7 +419,7 @@ def _ellipsoidal(earth, where):
|
|
|
416
419
|
return _EWGS84 if earth in (_WGS84, _EWGS84) else (
|
|
417
420
|
earth if isinstance(earth, Ellipsoid) else
|
|
418
421
|
(earth if isinstance(earth, Datum) else # PYCHOK indent
|
|
419
|
-
_ellipsoidal_datum(earth,
|
|
422
|
+
_ellipsoidal_datum(earth, name__=where)).ellipsoid)
|
|
420
423
|
|
|
421
424
|
|
|
422
425
|
def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
|
|
@@ -427,35 +430,31 @@ def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
|
|
|
427
430
|
@arg lon1: Start longitude (C{degrees}).
|
|
428
431
|
@arg lat2: End latitude (C{degrees}).
|
|
429
432
|
@arg lon2: End longitude (C{degrees}).
|
|
430
|
-
@kwarg radius: Mean earth radius (C{meter}), datum (L{Datum})
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
@kwarg adjust_limit_wrap: Optional keyword arguments for
|
|
434
|
-
function L{equirectangular_}.
|
|
433
|
+
@kwarg radius: Mean earth radius (C{meter}), datum (L{Datum}) or ellipsoid
|
|
434
|
+
(L{Ellipsoid}, L{Ellipsoid2} or L{a_f2Tuple}).
|
|
435
|
+
@kwarg adjust_limit_wrap: Optional keyword arguments for function L{equirectangular4}.
|
|
435
436
|
|
|
436
|
-
@return: Distance (C{meter}, same units as B{C{radius}} or
|
|
437
|
-
the ellipsoid or datum axes).
|
|
437
|
+
@return: Distance (C{meter}, same units as B{C{radius}} or the ellipsoid or datum axes).
|
|
438
438
|
|
|
439
439
|
@raise TypeError: Invalid B{C{radius}}.
|
|
440
440
|
|
|
441
|
-
@see: Function L{
|
|
442
|
-
|
|
443
|
-
approximate or accurate distance functions.
|
|
441
|
+
@see: Function L{equirectangular4} for more details, the available B{C{options}},
|
|
442
|
+
errors, restrictions and other, approximate or accurate distance functions.
|
|
444
443
|
'''
|
|
445
|
-
d = sqrt(
|
|
444
|
+
d = sqrt(equirectangular4(Lat(lat1=lat1), Lon(lon1=lon1),
|
|
446
445
|
Lat(lat2=lat2), Lon(lon2=lon2),
|
|
447
446
|
**adjust_limit_wrap).distance2) # PYCHOK 4 vs 2-3
|
|
448
447
|
return degrees2m(d, radius=_mean_radius(radius, lat1, lat2))
|
|
449
448
|
|
|
450
449
|
|
|
451
450
|
def _equirectangular(lat1, lon1, lat2, lon2, **adjust_limit_wrap):
|
|
452
|
-
'''(INTERNAL) Helper for the L{frechet.
|
|
451
|
+
'''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
|
|
453
452
|
and L{hausdorff._HausdorffMeterRedians} classes.
|
|
454
453
|
'''
|
|
455
|
-
return
|
|
454
|
+
return equirectangular4(lat1, lon1, lat2, lon2, **adjust_limit_wrap).distance2 * _RADIANS2
|
|
456
455
|
|
|
457
456
|
|
|
458
|
-
def
|
|
457
|
+
def equirectangular4(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
|
|
459
458
|
'''Compute the distance between two points using the U{Equirectangular Approximation
|
|
460
459
|
/ Projection<https://www.Movable-Type.co.UK/scripts/latlong.html#equirectangular>}.
|
|
461
460
|
|
|
@@ -466,15 +465,15 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
|
|
|
466
465
|
@arg lon1: Start longitude (C{degrees}).
|
|
467
466
|
@arg lat2: End latitude (C{degrees}).
|
|
468
467
|
@arg lon2: End longitude (C{degrees}).
|
|
469
|
-
@kwarg adjust: Adjust the wrapped, unrolled longitudinal delta
|
|
470
|
-
|
|
471
|
-
@kwarg limit: Optional limit for lat- and longitudinal deltas
|
|
472
|
-
|
|
473
|
-
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}}
|
|
474
|
-
|
|
468
|
+
@kwarg adjust: Adjust the wrapped, unrolled longitudinal delta by the cosine
|
|
469
|
+
of the mean latitude (C{bool}).
|
|
470
|
+
@kwarg limit: Optional limit for lat- and longitudinal deltas (C{degrees}) or
|
|
471
|
+
C{None} or C{0} for unlimited.
|
|
472
|
+
@kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{lat2}} and
|
|
473
|
+
B{C{lon2}} (C{bool}).
|
|
475
474
|
|
|
476
|
-
@return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon,
|
|
477
|
-
|
|
475
|
+
@return: A L{Distance4Tuple}C{(distance2, delta_lat, delta_lon, unroll_lon2)}
|
|
476
|
+
in C{degrees squared}.
|
|
478
477
|
|
|
479
478
|
@raise LimitError: If the lat- and/or longitudinal delta exceeds the
|
|
480
479
|
B{C{-limit..limit}} range and L{pygeodesy.limiterrors}
|
|
@@ -495,7 +494,7 @@ def equirectangular_(lat1, lon1, lat2, lon2, adjust=True, limit=45, wrap=False):
|
|
|
495
494
|
d = max(fabs(d_lat), fabs(d_lon))
|
|
496
495
|
if d > limit:
|
|
497
496
|
t = _SPACE_(_delta_, Fmt.PAREN_g(d), Fmt.exceeds_limit(limit))
|
|
498
|
-
s = unstr(
|
|
497
|
+
s = unstr(equirectangular4, lat1, lon1, lat2, lon2,
|
|
499
498
|
limit=limit, wrap=wrap)
|
|
500
499
|
raise LimitError(s, txt=t)
|
|
501
500
|
|
|
@@ -548,9 +547,9 @@ def euclidean_(phi2, phi1, lam21, adjust=True):
|
|
|
548
547
|
@return: Angular distance (C{radians}).
|
|
549
548
|
|
|
550
549
|
@see: Functions L{euclid}, L{euclidean}, L{cosineAndoyerLambert_},
|
|
551
|
-
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
552
|
-
L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
|
|
553
|
-
and L{vincentys_}.
|
|
550
|
+
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
551
|
+
L{flatLocal_}/L{hubeny_}, L{flatPolar_}, L{haversine_},
|
|
552
|
+
L{thomas_} and L{vincentys_}.
|
|
554
553
|
'''
|
|
555
554
|
if adjust:
|
|
556
555
|
lam21 *= _scale_rad(phi2, phi1)
|
|
@@ -863,8 +862,8 @@ def flatLocal_(phi2, phi1, lam21, datum=_WGS84, scaled=True):
|
|
|
863
862
|
|
|
864
863
|
@see: Functions L{flatLocal} or L{hubeny}, L{cosineAndoyerLambert_},
|
|
865
864
|
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_}, L{flatPolar_},
|
|
866
|
-
L{
|
|
867
|
-
|
|
865
|
+
L{euclidean_}, L{haversine_}, L{thomas_} and L{vincentys_} and
|
|
866
|
+
U{local, flat earth approximation
|
|
868
867
|
<https://www.EdWilliams.org/avform.htm#flat>}.
|
|
869
868
|
'''
|
|
870
869
|
E = _ellipsoidal(datum, flatLocal_)
|
|
@@ -917,8 +916,8 @@ def flatPolar_(phi2, phi1, lam21):
|
|
|
917
916
|
|
|
918
917
|
@see: Functions L{flatPolar}, L{cosineAndoyerLambert_},
|
|
919
918
|
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
920
|
-
L{
|
|
921
|
-
L{
|
|
919
|
+
L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{haversine_},
|
|
920
|
+
L{thomas_} and L{vincentys_}.
|
|
922
921
|
'''
|
|
923
922
|
a = fabs(PI_2 - phi1) # co-latitude
|
|
924
923
|
b = fabs(PI_2 - phi2) # co-latitude
|
|
@@ -940,7 +939,7 @@ def _hartzell(pov, los, earth, **kwds):
|
|
|
940
939
|
if earth is None:
|
|
941
940
|
earth = pov.datum
|
|
942
941
|
else:
|
|
943
|
-
earth = _spherical_datum(earth,
|
|
942
|
+
earth = _spherical_datum(earth, name__=hartzell)
|
|
944
943
|
pov = pov.toDatum(earth)
|
|
945
944
|
h = pov.height
|
|
946
945
|
if h < 0: # EPS0
|
|
@@ -949,26 +948,25 @@ def _hartzell(pov, los, earth, **kwds):
|
|
|
949
948
|
return hartzell(pov, los=los, earth=earth, **kwds) if h > 0 else pov # EPS0
|
|
950
949
|
|
|
951
950
|
|
|
952
|
-
def hartzell(pov, los=False, earth=_WGS84,
|
|
951
|
+
def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
|
|
953
952
|
'''Compute the intersection of the earth's surface and a Line-Of-Sight from
|
|
954
953
|
a Point-Of-View in space.
|
|
955
954
|
|
|
956
955
|
@arg pov: Point-Of-View outside the earth (C{LatLon}, C{Cartesian},
|
|
957
956
|
L{Ecef9Tuple} or L{Vector3d}).
|
|
958
957
|
@kwarg los: Line-Of-Sight, I{direction} to earth (L{Los}, L{Vector3d}),
|
|
959
|
-
C{True} for the I{normal, plumb} onto the surface or
|
|
960
|
-
|
|
958
|
+
C{True} for the I{normal, plumb} onto the surface or C{False}
|
|
959
|
+
or C{None} to point to the center of the earth.
|
|
961
960
|
@kwarg earth: The earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
|
|
962
961
|
L{a_f2Tuple} or a C{scalar} earth radius in C{meter}).
|
|
963
|
-
@kwarg
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
from B{C{earth}}.
|
|
962
|
+
@kwarg name_LatLon_and_kwds: Optional, overriding C{B{name}="hartzell"}
|
|
963
|
+
(C{str}), class C{B{LatLon}=None} to return the intersection
|
|
964
|
+
plus additional C{LatLon} keyword arguments, include the
|
|
965
|
+
B{C{datum}} if different and to convert from B{C{earth}}.
|
|
968
966
|
|
|
969
|
-
@return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or
|
|
970
|
-
|
|
971
|
-
|
|
967
|
+
@return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or the
|
|
968
|
+
given B{C{LatLon}} instance) with attribute C{heigth} set to the
|
|
969
|
+
distance to the B{C{pov}}.
|
|
972
970
|
|
|
973
971
|
@raise IntersectionError: Invalid B{C{pov}} or B{C{pov}} inside the earth or
|
|
974
972
|
invalid B{C{los}} or B{C{los}} points outside or
|
|
@@ -979,23 +977,23 @@ def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
|
|
|
979
977
|
@see: Class L{Los}, functions L{tyr3d} and L{hartzell4} and methods
|
|
980
978
|
L{Ellipsoid.hartzell4} and any C{Cartesian.hartzell} and C{LatLon.hartzell}.
|
|
981
979
|
'''
|
|
982
|
-
n = hartzell
|
|
983
|
-
D = earth if isinstance(earth, Datum) else _spherical_datum(earth, name=n)
|
|
980
|
+
n, LatLon_and_kwds = _name2__(name_LatLon_and_kwds, name__=hartzell)
|
|
984
981
|
try:
|
|
982
|
+
D = _spherical_datum(earth, name__=hartzell)
|
|
985
983
|
r, h, i = _MODS.triaxials._hartzell3(pov, los, D.ellipsoid._triaxial)
|
|
986
984
|
|
|
987
|
-
r = _xnamed(r, name or n)
|
|
988
985
|
C = _MODS.cartesianBase.CartesianBase
|
|
989
986
|
if LatLon_and_kwds:
|
|
990
|
-
c = C(r, datum=D
|
|
987
|
+
c = C(r, datum=D)
|
|
991
988
|
r = c.toLatLon(**_xkwds(LatLon_and_kwds, height=h))
|
|
992
989
|
elif isinstance(r, C):
|
|
993
990
|
r.height = h
|
|
994
991
|
if i:
|
|
995
992
|
r._iteration = i
|
|
996
993
|
except Exception as x:
|
|
997
|
-
raise IntersectionError(pov=pov, los=los, earth=earth, cause=x,
|
|
998
|
-
|
|
994
|
+
raise IntersectionError(pov=pov, los=los, earth=earth, cause=x,
|
|
995
|
+
**LatLon_and_kwds)
|
|
996
|
+
return _xnamed(r, n) if n else r
|
|
999
997
|
|
|
1000
998
|
|
|
1001
999
|
def haversine(lat1, lon1, lat2, lon2, radius=R_M, wrap=False):
|
|
@@ -1042,8 +1040,8 @@ def haversine_(phi2, phi1, lam21):
|
|
|
1042
1040
|
|
|
1043
1041
|
@see: Functions L{haversine}, L{cosineAndoyerLambert_},
|
|
1044
1042
|
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
1045
|
-
L{
|
|
1046
|
-
L{
|
|
1043
|
+
L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
|
|
1044
|
+
L{thomas_} and L{vincentys_}.
|
|
1047
1045
|
|
|
1048
1046
|
@note: See note at function L{vincentys_}.
|
|
1049
1047
|
'''
|
|
@@ -1108,8 +1106,8 @@ def heightOrthometric(h_ll, N):
|
|
|
1108
1106
|
|
|
1109
1107
|
|
|
1110
1108
|
def horizon(height, radius=R_M, refraction=False):
|
|
1111
|
-
'''Determine the distance to the horizon from a given altitude
|
|
1112
|
-
|
|
1109
|
+
'''Determine the distance to the horizon from a given altitude above the
|
|
1110
|
+
(spherical) earth.
|
|
1113
1111
|
|
|
1114
1112
|
@arg height: Altitude (C{meter} or same units as B{C{radius}}).
|
|
1115
1113
|
@kwarg radius: Optional mean earth radius (C{meter}).
|
|
@@ -1139,8 +1137,8 @@ class _idllmn6(object): # see also .geodesicw._wargs, .latlonBase._toCartesian3
|
|
|
1139
1137
|
if wrap:
|
|
1140
1138
|
_, lat2, lon2 = _Wrap.latlon3(lon1, lat2, lon2, wrap)
|
|
1141
1139
|
kwds = _xkwds(kwds, wrap=wrap) # for _xError
|
|
1142
|
-
m =
|
|
1143
|
-
n = (intersections2 if s else intersection2)
|
|
1140
|
+
m = small if small is _100km else Meter_(small=small)
|
|
1141
|
+
n = _dunder_nameof(intersections2 if s else intersection2)
|
|
1144
1142
|
if datum is None or euclidean(lat1, lon1, lat2, lon2) < m:
|
|
1145
1143
|
d, m = None, _MODS.vector3d
|
|
1146
1144
|
_i = m._intersects2 if s else m._intersect3d3
|
|
@@ -1398,13 +1396,13 @@ def isnormal_(phi, lam, eps=0):
|
|
|
1398
1396
|
return (PI_2 - fabs(phi)) >= eps and (PI - fabs(lam)) >= eps
|
|
1399
1397
|
|
|
1400
1398
|
|
|
1401
|
-
def latlon2n_xyz(lat, lon, name
|
|
1399
|
+
def latlon2n_xyz(lat, lon, **name):
|
|
1402
1400
|
'''Convert lat-, longitude to C{n-vector} (I{normal} to the
|
|
1403
1401
|
earth's surface) X, Y and Z components.
|
|
1404
1402
|
|
|
1405
1403
|
@arg lat: Latitude (C{degrees}).
|
|
1406
1404
|
@arg lon: Longitude (C{degrees}).
|
|
1407
|
-
@kwarg name: Optional name (C{str}).
|
|
1405
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1408
1406
|
|
|
1409
1407
|
@return: A L{Vector3Tuple}C{(x, y, z)}.
|
|
1410
1408
|
|
|
@@ -1429,12 +1427,12 @@ def _normal2(a, b, n_2, n, n2):
|
|
|
1429
1427
|
return float0_(a, b)
|
|
1430
1428
|
|
|
1431
1429
|
|
|
1432
|
-
def normal(lat, lon, name
|
|
1430
|
+
def normal(lat, lon, **name):
|
|
1433
1431
|
'''Normalize a lat- I{and} longitude pair in C{degrees}.
|
|
1434
1432
|
|
|
1435
1433
|
@arg lat: Latitude (C{degrees}).
|
|
1436
1434
|
@arg lon: Longitude (C{degrees}).
|
|
1437
|
-
@kwarg name: Optional name (C{str}).
|
|
1435
|
+
@kwarg name: Optional, overriding C{B{name}="normal"} (C{str}).
|
|
1438
1436
|
|
|
1439
1437
|
@return: L{LatLon2Tuple}C{(lat, lon)} with C{abs(lat) <= 90}
|
|
1440
1438
|
and C{abs(lon) <= 180}.
|
|
@@ -1442,15 +1440,15 @@ def normal(lat, lon, name=NN):
|
|
|
1442
1440
|
@see: Functions L{normal_} and L{isnormal}.
|
|
1443
1441
|
'''
|
|
1444
1442
|
return LatLon2Tuple(*_normal2(lat, lon, _90_0, _180_0, _360_0),
|
|
1445
|
-
name=name
|
|
1443
|
+
name=_name__(name, name__=normal))
|
|
1446
1444
|
|
|
1447
1445
|
|
|
1448
|
-
def normal_(phi, lam, name
|
|
1446
|
+
def normal_(phi, lam, **name):
|
|
1449
1447
|
'''Normalize a lat- I{and} longitude pair in C{radians}.
|
|
1450
1448
|
|
|
1451
1449
|
@arg phi: Latitude (C{radians}).
|
|
1452
1450
|
@arg lam: Longitude (C{radians}).
|
|
1453
|
-
@kwarg name: Optional name (C{str}).
|
|
1451
|
+
@kwarg name: Optional, overriding C{B{name}="normal_"} (C{str}).
|
|
1454
1452
|
|
|
1455
1453
|
@return: L{PhiLam2Tuple}C{(phi, lam)} with C{abs(phi) <= PI/2}
|
|
1456
1454
|
and C{abs(lam) <= PI}.
|
|
@@ -1458,45 +1456,45 @@ def normal_(phi, lam, name=NN):
|
|
|
1458
1456
|
@see: Functions L{normal} and L{isnormal_}.
|
|
1459
1457
|
'''
|
|
1460
1458
|
return PhiLam2Tuple(*_normal2(phi, lam, PI_2, PI, PI2),
|
|
1461
|
-
name=name
|
|
1459
|
+
name=_name__(name, name__=normal_))
|
|
1462
1460
|
|
|
1463
1461
|
|
|
1464
|
-
def _2n_xyz(name, sa, ca, sb, cb):
|
|
1462
|
+
def _2n_xyz(name, sa, ca, sb, cb): # name always **name
|
|
1465
1463
|
'''(INTERNAL) Helper for C{latlon2n_xyz} and C{philam2n_xyz}.
|
|
1466
1464
|
'''
|
|
1467
1465
|
# Kenneth Gade eqn 3, but using right-handed
|
|
1468
1466
|
# vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N
|
|
1469
|
-
return Vector3Tuple(ca * cb, ca * sb, sa, name
|
|
1467
|
+
return Vector3Tuple(ca * cb, ca * sb, sa, **name)
|
|
1470
1468
|
|
|
1471
1469
|
|
|
1472
|
-
def n_xyz2latlon(x, y, z, name
|
|
1470
|
+
def n_xyz2latlon(x, y, z, **name):
|
|
1473
1471
|
'''Convert C{n-vector} components to lat- and longitude in C{degrees}.
|
|
1474
1472
|
|
|
1475
1473
|
@arg x: X component (C{scalar}).
|
|
1476
1474
|
@arg y: Y component (C{scalar}).
|
|
1477
1475
|
@arg z: Z component (C{scalar}).
|
|
1478
|
-
@kwarg name: Optional name (C{str}).
|
|
1476
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1479
1477
|
|
|
1480
1478
|
@return: A L{LatLon2Tuple}C{(lat, lon)}.
|
|
1481
1479
|
|
|
1482
1480
|
@see: Function L{n_xyz2philam}.
|
|
1483
1481
|
'''
|
|
1484
|
-
return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), name
|
|
1482
|
+
return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), **name)
|
|
1485
1483
|
|
|
1486
1484
|
|
|
1487
|
-
def n_xyz2philam(x, y, z, name
|
|
1485
|
+
def n_xyz2philam(x, y, z, **name):
|
|
1488
1486
|
'''Convert C{n-vector} components to lat- and longitude in C{radians}.
|
|
1489
1487
|
|
|
1490
1488
|
@arg x: X component (C{scalar}).
|
|
1491
1489
|
@arg y: Y component (C{scalar}).
|
|
1492
1490
|
@arg z: Z component (C{scalar}).
|
|
1493
|
-
@kwarg name: Optional name (C{str}).
|
|
1491
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1494
1492
|
|
|
1495
1493
|
@return: A L{PhiLam2Tuple}C{(phi, lam)}.
|
|
1496
1494
|
|
|
1497
1495
|
@see: Function L{n_xyz2latlon}.
|
|
1498
1496
|
'''
|
|
1499
|
-
return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), name
|
|
1497
|
+
return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), **name)
|
|
1500
1498
|
|
|
1501
1499
|
|
|
1502
1500
|
def _opposes(d, m, n, n2):
|
|
@@ -1539,7 +1537,7 @@ def opposing_(radians1, radians2, margin=PI_2):
|
|
|
1539
1537
|
return _opposes(radians2 - radians1, m, PI, PI2)
|
|
1540
1538
|
|
|
1541
1539
|
|
|
1542
|
-
def philam2n_xyz(phi, lam, name
|
|
1540
|
+
def philam2n_xyz(phi, lam, **name):
|
|
1543
1541
|
'''Convert lat-, longitude to C{n-vector} (I{normal} to the
|
|
1544
1542
|
earth's surface) X, Y and Z components.
|
|
1545
1543
|
|
|
@@ -1557,14 +1555,29 @@ def philam2n_xyz(phi, lam, name=NN):
|
|
|
1557
1555
|
return _2n_xyz(name, *sincos2_(phi, lam))
|
|
1558
1556
|
|
|
1559
1557
|
|
|
1560
|
-
def
|
|
1558
|
+
def _Propy(func, nargs, kwds):
|
|
1559
|
+
'''(INTERNAL) Helper for the C{frechet.[-]Frechet**} and
|
|
1560
|
+
C{hausdorff.[-]Hausdorff*} classes.
|
|
1561
|
+
'''
|
|
1562
|
+
try:
|
|
1563
|
+
_xcallable(distance=func)
|
|
1564
|
+
# assert _args_kwds_count2(func)[0] == nargs + int(ismethod(func))
|
|
1565
|
+
_ = func(*_0_0s(nargs), **kwds)
|
|
1566
|
+
except Exception as x:
|
|
1567
|
+
t = unstr(func, **kwds)
|
|
1568
|
+
raise _TypeError(t, cause=x)
|
|
1569
|
+
return func
|
|
1570
|
+
|
|
1571
|
+
|
|
1572
|
+
def _radical2(d, r1, r2, **name): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
|
|
1561
1573
|
# (INTERNAL) See C{radical2} below
|
|
1562
1574
|
# assert d > EPS0
|
|
1563
|
-
r =
|
|
1564
|
-
|
|
1575
|
+
r = fsumf_(_1_0, (r1 / d)**2, -(r2 / d)**2) * _0_5
|
|
1576
|
+
n = _name__(name, name__=radical2)
|
|
1577
|
+
return Radical2Tuple(max(_0_0, min(_1_0, r)), r * d, name=n)
|
|
1565
1578
|
|
|
1566
1579
|
|
|
1567
|
-
def radical2(distance, radius1, radius2):
|
|
1580
|
+
def radical2(distance, radius1, radius2, **name):
|
|
1568
1581
|
'''Compute the I{radical ratio} and I{radical line} of two
|
|
1569
1582
|
U{intersecting circles<https://MathWorld.Wolfram.com/
|
|
1570
1583
|
Circle-CircleIntersection.html>}.
|
|
@@ -1575,6 +1588,7 @@ def radical2(distance, radius1, radius2):
|
|
|
1575
1588
|
@arg distance: Distance between the circle centers (C{scalar}).
|
|
1576
1589
|
@arg radius1: Radius of the first circle (C{scalar}).
|
|
1577
1590
|
@arg radius2: Radius of the second circle (C{scalar}).
|
|
1591
|
+
@kwarg name: Optional C{B{name}=NN} (C{str}).
|
|
1578
1592
|
|
|
1579
1593
|
@return: A L{Radical2Tuple}C{(ratio, xline)} where C{0.0 <=
|
|
1580
1594
|
ratio <= 1.0} and C{xline} is along the B{C{distance}}.
|
|
@@ -1594,8 +1608,8 @@ def radical2(distance, radius1, radius2):
|
|
|
1594
1608
|
if d > (r1 + r2):
|
|
1595
1609
|
raise IntersectionError(distance=d, radius1=r1, radius2=r2,
|
|
1596
1610
|
txt=_too_(_distant_))
|
|
1597
|
-
return _radical2(d, r1, r2) if d > EPS0 else \
|
|
1598
|
-
Radical2Tuple(_0_5, _0_0)
|
|
1611
|
+
return _radical2(d, r1, r2, **name) if d > EPS0 else \
|
|
1612
|
+
Radical2Tuple(_0_5, _0_0, **name)
|
|
1599
1613
|
|
|
1600
1614
|
|
|
1601
1615
|
class Radical2Tuple(_NamedTuple):
|
|
@@ -1607,7 +1621,7 @@ class Radical2Tuple(_NamedTuple):
|
|
|
1607
1621
|
|
|
1608
1622
|
|
|
1609
1623
|
def _radistance(inst):
|
|
1610
|
-
'''(INTERNAL) Helper for the L{frechet.
|
|
1624
|
+
'''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
|
|
1611
1625
|
and L{hausdorff._HausdorffMeterRedians} classes.
|
|
1612
1626
|
'''
|
|
1613
1627
|
wrap_, kwds_ = _xkwds_pop2(inst._kwds, wrap=False)
|
|
@@ -1695,8 +1709,8 @@ def thomas_(phi2, phi1, lam21, datum=_WGS84):
|
|
|
1695
1709
|
|
|
1696
1710
|
@see: Functions L{thomas}, L{cosineAndoyerLambert_},
|
|
1697
1711
|
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
1698
|
-
L{
|
|
1699
|
-
L{
|
|
1712
|
+
L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
|
|
1713
|
+
L{haversine_} and L{vincentys_} and U{Geodesy-PHP
|
|
1700
1714
|
<https://GitHub.com/jtejido/geodesy-php/blob/master/src/Geodesy/
|
|
1701
1715
|
Distance/ThomasFormula.php>}.
|
|
1702
1716
|
'''
|
|
@@ -1778,8 +1792,8 @@ def vincentys_(phi2, phi1, lam21):
|
|
|
1778
1792
|
|
|
1779
1793
|
@see: Functions L{vincentys}, L{cosineAndoyerLambert_},
|
|
1780
1794
|
L{cosineForsytheAndoyerLambert_}, L{cosineLaw_},
|
|
1781
|
-
L{
|
|
1782
|
-
L{
|
|
1795
|
+
L{euclidean_}, L{flatLocal_}/L{hubeny_}, L{flatPolar_},
|
|
1796
|
+
L{haversine_} and L{thomas_}.
|
|
1783
1797
|
|
|
1784
1798
|
@note: Functions L{vincentys_}, L{haversine_} and L{cosineLaw_}
|
|
1785
1799
|
produce equivalent results, but L{vincentys_} is suitable
|