pygeodesy 25.4.8__py2.py3-none-any.whl → 25.5.5__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/__init__.py +36 -31
- pygeodesy/__main__.py +3 -3
- pygeodesy/albers.py +29 -36
- pygeodesy/auxilats/_CX_4.py +2 -2
- pygeodesy/auxilats/_CX_6.py +2 -2
- pygeodesy/auxilats/_CX_8.py +2 -2
- pygeodesy/auxilats/_CX_Rs.py +9 -9
- pygeodesy/auxilats/__init__.py +3 -3
- pygeodesy/auxilats/__main__.py +8 -6
- pygeodesy/auxilats/auxAngle.py +2 -2
- pygeodesy/auxilats/auxLat.py +5 -5
- pygeodesy/auxilats/auxily.py +5 -3
- pygeodesy/azimuthal.py +7 -6
- pygeodesy/basics.py +32 -18
- pygeodesy/booleans.py +18 -16
- pygeodesy/cartesianBase.py +26 -24
- pygeodesy/clipy.py +11 -10
- pygeodesy/constants.py +11 -10
- pygeodesy/css.py +14 -11
- pygeodesy/datums.py +8 -8
- pygeodesy/deprecated/bases.py +2 -2
- pygeodesy/deprecated/classes.py +2 -2
- pygeodesy/deprecated/consterns.py +4 -4
- pygeodesy/dms.py +8 -8
- pygeodesy/ecef.py +22 -29
- pygeodesy/ecefLocals.py +186 -0
- pygeodesy/elevations.py +9 -8
- pygeodesy/ellipsoidalBase.py +19 -8
- pygeodesy/ellipsoidalBaseDI.py +17 -15
- pygeodesy/ellipsoidalNvector.py +6 -3
- pygeodesy/ellipsoidalVincenty.py +4 -1
- pygeodesy/ellipsoids.py +186 -164
- pygeodesy/elliptic.py +9 -9
- pygeodesy/errors.py +44 -43
- pygeodesy/etm.py +7 -7
- pygeodesy/fmath.py +30 -14
- pygeodesy/formy.py +11 -12
- pygeodesy/frechet.py +216 -109
- pygeodesy/fstats.py +5 -4
- pygeodesy/fsums.py +79 -78
- pygeodesy/gars.py +4 -3
- pygeodesy/geodesici.py +15 -14
- pygeodesy/geodesicw.py +34 -32
- pygeodesy/geodesicx/__init__.py +1 -1
- pygeodesy/geodesicx/__main__.py +11 -9
- pygeodesy/geodesicx/gx.py +30 -33
- pygeodesy/geodesicx/gxarea.py +2 -2
- pygeodesy/geodesicx/gxline.py +5 -5
- pygeodesy/geodsolve.py +18 -17
- pygeodesy/geohash.py +5 -5
- pygeodesy/geoids.py +34 -31
- pygeodesy/hausdorff.py +17 -13
- pygeodesy/heights.py +2 -4
- pygeodesy/internals.py +28 -44
- pygeodesy/interns.py +10 -7
- pygeodesy/iters.py +8 -8
- pygeodesy/karney.py +68 -62
- pygeodesy/ktm.py +5 -5
- pygeodesy/latlonBase.py +20 -21
- pygeodesy/lazily.py +104 -78
- pygeodesy/lcc.py +11 -9
- pygeodesy/ltp.py +56 -58
- pygeodesy/ltpTuples.py +35 -36
- pygeodesy/mgrs.py +7 -6
- pygeodesy/named.py +48 -177
- pygeodesy/nvectorBase.py +7 -7
- pygeodesy/osgr.py +9 -8
- pygeodesy/points.py +12 -10
- pygeodesy/props.py +25 -25
- pygeodesy/resections.py +83 -80
- pygeodesy/rhumb/__init__.py +1 -1
- pygeodesy/rhumb/aux_.py +7 -7
- pygeodesy/rhumb/bases.py +22 -20
- pygeodesy/rhumb/ekx.py +6 -6
- pygeodesy/rhumb/solve.py +15 -15
- pygeodesy/solveBase.py +3 -3
- pygeodesy/sphericalBase.py +6 -6
- pygeodesy/sphericalNvector.py +6 -5
- pygeodesy/sphericalTrigonometry.py +8 -7
- pygeodesy/streprs.py +14 -14
- pygeodesy/trf.py +14 -12
- pygeodesy/triaxials.py +29 -26
- pygeodesy/units.py +5 -4
- pygeodesy/unitsBase.py +5 -4
- pygeodesy/ups.py +3 -3
- pygeodesy/utily.py +4 -4
- pygeodesy/utmups.py +4 -4
- pygeodesy/utmupsBase.py +110 -18
- pygeodesy/vector2d.py +20 -13
- pygeodesy/vector3d.py +7 -6
- pygeodesy/webmercator.py +6 -5
- pygeodesy/wgrs.py +6 -5
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/METADATA +30 -25
- pygeodesy-25.5.5.dist-info/RECORD +119 -0
- pygeodesy-25.4.8.dist-info/RECORD +0 -118
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/WHEEL +0 -0
- {pygeodesy-25.4.8.dist-info → pygeodesy-25.5.5.dist-info}/top_level.txt +0 -0
pygeodesy/triaxials.py
CHANGED
|
@@ -17,20 +17,20 @@ see the U{GeographicLib<https://GeographicLib.SourceForge.io>} documentation.
|
|
|
17
17
|
@var Triaxials.Amalthea: Triaxial(name='Amalthea', a=125000, b=73000, c=64000, e2ab=0.658944, e2bc=0.231375493, e2ac=0.737856, volume=2446253479595252, area=93239507787.490371704, area_p=93212299402.670425415)
|
|
18
18
|
@var Triaxials.Ariel: Triaxial(name='Ariel', a=581100, b=577900, c=577700, e2ab=0.01098327, e2bc=0.000692042, e2ac=0.011667711, volume=812633172614203904, area=4211301462766.580078125, area_p=4211301574065.829589844)
|
|
19
19
|
@var Triaxials.Earth: Triaxial(name='Earth', a=6378173.435, b=6378103.9, c=6356754.399999999, e2ab=0.000021804, e2bc=0.006683418, e2ac=0.006705077, volume=1083208241574987694080, area=510065911057441.0625, area_p=510065915922713.6875)
|
|
20
|
-
@var Triaxials.Enceladus: Triaxial(name='Enceladus', a=256600, b=251400, c=248300, e2ab=0.040119337, e2bc=0.024509841, e2ac=0.06364586, volume=67094551514082248, area=798618496278.596679688, area_p=798619018175.
|
|
20
|
+
@var Triaxials.Enceladus: Triaxial(name='Enceladus', a=256600, b=251400, c=248300, e2ab=0.040119337, e2bc=0.024509841, e2ac=0.06364586, volume=67094551514082248, area=798618496278.596679688, area_p=798619018175.109985352)
|
|
21
21
|
@var Triaxials.Europa: Triaxial(name='Europa', a=1564130, b=1561230, c=1560930, e2ab=0.003704694, e2bc=0.000384275, e2ac=0.004087546, volume=15966575194402123776, area=30663773697323.51953125, area_p=30663773794562.45703125)
|
|
22
22
|
@var Triaxials.Io: Triaxial(name='Io', a=1829400, b=1819300, c=1815700, e2ab=0.011011391, e2bc=0.003953651, e2ac=0.014921506, volume=25313121117889765376, area=41691875849096.7421875, area_p=41691877397441.2109375)
|
|
23
23
|
@var Triaxials.Mars: Triaxial(name='Mars', a=3394600, b=3393300, c=3376300, e2ab=0.000765776, e2bc=0.009994646, e2ac=0.010752768, volume=162907283585817247744, area=144249140795107.4375, area_p=144249144150662.15625)
|
|
24
|
-
@var Triaxials.Mimas: Triaxial(name='Mimas', a=207400, b=196800, c=190600, e2ab=0.09960581, e2bc=0.062015624, e2ac=0.155444317, volume=32587072869017956, area=493855762247.
|
|
25
|
-
@var Triaxials.Miranda: Triaxial(name='Miranda', a=240400, b=234200, c=232900, e2ab=0.050915557, e2bc=0.011070811, e2ac=0.061422691, volume=54926187094835456, area=698880863325.
|
|
26
|
-
@var Triaxials.Moon: Triaxial(name='Moon', a=1735550, b=1735324, c=1734898, e2ab=0.000260419, e2bc=0.000490914, e2ac=0.000751206, volume=21886698675223740416, area=37838824729886.09375, area_p=37838824733332.
|
|
24
|
+
@var Triaxials.Mimas: Triaxial(name='Mimas', a=207400, b=196800, c=190600, e2ab=0.09960581, e2bc=0.062015624, e2ac=0.155444317, volume=32587072869017956, area=493855762247.691833496, area_p=493857714107.9375)
|
|
25
|
+
@var Triaxials.Miranda: Triaxial(name='Miranda', a=240400, b=234200, c=232900, e2ab=0.050915557, e2bc=0.011070811, e2ac=0.061422691, volume=54926187094835456, area=698880863325.757080078, area_p=698881306767.950317383)
|
|
26
|
+
@var Triaxials.Moon: Triaxial(name='Moon', a=1735550, b=1735324, c=1734898, e2ab=0.000260419, e2bc=0.000490914, e2ac=0.000751206, volume=21886698675223740416, area=37838824729886.09375, area_p=37838824733332.21875)
|
|
27
27
|
@var Triaxials.Tethys: Triaxial(name='Tethys', a=535600, b=528200, c=525800, e2ab=0.027441672, e2bc=0.009066821, e2ac=0.036259685, volume=623086233855821440, area=3528073490771.394042969, area_p=3528074261832.738769531)
|
|
28
28
|
@var Triaxials.WGS84_35: Triaxial(name='WGS84_35', a=6378172, b=6378102, c=6356752.314245179, e2ab=0.00002195, e2bc=0.006683478, e2ac=0.006705281, volume=1083207319768789942272, area=510065621722018.125, area_p=510065626587483.3125)
|
|
29
29
|
'''
|
|
30
30
|
# make sure int/int division yields float quotient, see .basics
|
|
31
31
|
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
32
32
|
|
|
33
|
-
from pygeodesy.basics import isLatLon, isscalar
|
|
33
|
+
from pygeodesy.basics import _isin, isLatLon, isscalar
|
|
34
34
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, INT0, PI2, PI_3, PI4, \
|
|
35
35
|
_EPS2e4, _SQRT2_2, float0_, isfinite, isnear1, _over, \
|
|
36
36
|
_0_0, _0_5, _1_0, _N_1_0, _64_0, _4_0 # PYCHOK used!
|
|
@@ -40,10 +40,10 @@ from pygeodesy.datums import Datum, _spherical_datum, _WGS84, Ellipsoid, _EWGS8
|
|
|
40
40
|
from pygeodesy.errors import _AssertionError, _ValueError
|
|
41
41
|
from pygeodesy.fmath import Fdot, fdot, fmean_, hypot, hypot_, norm2, sqrt0
|
|
42
42
|
from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1f_
|
|
43
|
-
from pygeodesy.interns import NN, _a_, _b_, _beta_, _c_, _distant_,
|
|
44
|
-
_height_, _inside_, _near_, _negative_,
|
|
45
|
-
_NOTEQUAL_, _null_, _opposite_, _outside_,
|
|
46
|
-
_spherical_, _too_, _x_, _y_
|
|
43
|
+
from pygeodesy.interns import NN, _a_, _b_, _beta_, _c_, _distant_, _DMAIN_, \
|
|
44
|
+
_finite_, _height_, _inside_, _near_, _negative_, \
|
|
45
|
+
_not_, _NOTEQUAL_, _null_, _opposite_, _outside_, \
|
|
46
|
+
_SPACE_, _spherical_, _too_, _x_, _y_
|
|
47
47
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .vector3d
|
|
48
48
|
from pygeodesy.named import _lazyNamedEnumItem as _lazy, _name__, _NamedEnum, \
|
|
49
49
|
_NamedEnumItem, _Pass
|
|
@@ -59,7 +59,7 @@ from pygeodesy.vector3d import _otherV3d, Vector3d, _ALL_LAZY, _MODS
|
|
|
59
59
|
from math import fabs, sqrt
|
|
60
60
|
|
|
61
61
|
__all__ = _ALL_LAZY.triaxials
|
|
62
|
-
__version__ = '
|
|
62
|
+
__version__ = '25.04.14'
|
|
63
63
|
|
|
64
64
|
_not_ordered_ = _not_('ordered')
|
|
65
65
|
_omega_ = 'omega'
|
|
@@ -258,7 +258,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
258
258
|
|
|
259
259
|
@Property_RO
|
|
260
260
|
def _a2_b2(self):
|
|
261
|
-
'''(INTERNAL) Get C{(a/b)**2}.
|
|
261
|
+
'''(INTERNAL) Get C{(a / b)**2}.
|
|
262
262
|
'''
|
|
263
263
|
a, b, _ = self._abc3
|
|
264
264
|
return (a / b)**2 if a != b else _1_0
|
|
@@ -321,7 +321,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
321
321
|
|
|
322
322
|
@Property_RO
|
|
323
323
|
def _c2_b2(self):
|
|
324
|
-
'''(INTERNAL) Get C{(c/b)**2}.
|
|
324
|
+
'''(INTERNAL) Get C{(c / b)**2}.
|
|
325
325
|
'''
|
|
326
326
|
_, b, c = self._abc3
|
|
327
327
|
return (c / b)**2 if b != c else _1_0
|
|
@@ -422,7 +422,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
422
422
|
raise TriaxialError(x=x, y=y, z=z, cause=e)
|
|
423
423
|
if h > 0 and self.sideOf(v, eps=EPS0) < 0:
|
|
424
424
|
h = -h # inside
|
|
425
|
-
n = _name__(name, name__=self.height4) #
|
|
425
|
+
n = _name__(name, name__=self.height4) # typename
|
|
426
426
|
return Vector4Tuple(x, y, z, h, iteration=i, name=n)
|
|
427
427
|
|
|
428
428
|
@Property_RO
|
|
@@ -507,7 +507,7 @@ class Triaxial_(_NamedEnumItem):
|
|
|
507
507
|
@return: 2-Tuple C{((a, b, c), ijk)} with C{a} >= C{b} >= C{c}
|
|
508
508
|
and C{ijk} a 3-tuple with the initial indices.
|
|
509
509
|
'''
|
|
510
|
-
i, j, k =
|
|
510
|
+
i, j, k = range(3)
|
|
511
511
|
if a < b:
|
|
512
512
|
a, b, i, j = b, a, j, i
|
|
513
513
|
if a < c:
|
|
@@ -1245,9 +1245,9 @@ def hartzell4(pov, los=False, tri_biax=_WGS84, **name):
|
|
|
1245
1245
|
'''Compute the intersection of a tri-/biaxial ellipsoid and a Line-Of-Sight from
|
|
1246
1246
|
a Point-Of-View outside.
|
|
1247
1247
|
|
|
1248
|
-
@arg pov: Point-Of-View outside the tri-/biaxial (C{Cartesian}, L{Ecef9Tuple}
|
|
1248
|
+
@arg pov: Point-Of-View outside the tri-/biaxial (C{Cartesian}, L{Ecef9Tuple},
|
|
1249
1249
|
C{LatLon} or L{Vector3d}).
|
|
1250
|
-
@kwarg los: Line-Of-Sight, I{direction} to the tri-/biaxial (L{Los}, L{Vector3d})
|
|
1250
|
+
@kwarg los: Line-Of-Sight, I{direction} to the tri-/biaxial (L{Los}, L{Vector3d})
|
|
1251
1251
|
or C{True} for the I{normal, perpendicular, plumb} to the surface of
|
|
1252
1252
|
the tri-/biaxial or C{False} or C{None} to point to its center.
|
|
1253
1253
|
@kwarg tri_biax: A triaxial (L{Triaxial}, L{Triaxial_}, L{JacobiConformal} or
|
|
@@ -1275,13 +1275,13 @@ def hartzell4(pov, los=False, tri_biax=_WGS84, **name):
|
|
|
1275
1275
|
T = tri_biax
|
|
1276
1276
|
else:
|
|
1277
1277
|
D = tri_biax if isinstance(tri_biax, Datum) else \
|
|
1278
|
-
_spherical_datum(tri_biax, name__=hartzell4) #
|
|
1278
|
+
_spherical_datum(tri_biax, name__=hartzell4) # typename
|
|
1279
1279
|
T = D.ellipsoid._triaxial
|
|
1280
1280
|
try:
|
|
1281
1281
|
v, h, i = _hartzell3(pov, los, T)
|
|
1282
1282
|
except Exception as x:
|
|
1283
1283
|
raise TriaxialError(pov=pov, los=los, tri_biax=tri_biax, cause=x)
|
|
1284
|
-
n = _name__(name, name__=hartzell4) #
|
|
1284
|
+
n = _name__(name, name__=hartzell4) # typename
|
|
1285
1285
|
return Vector4Tuple(v.x, v.y, v.z, h, iteration=i, name=n)
|
|
1286
1286
|
|
|
1287
1287
|
|
|
@@ -1478,19 +1478,18 @@ def _rootNd(r, s, u, v, w, g, eps=EPS0):
|
|
|
1478
1478
|
'''
|
|
1479
1479
|
u *= r
|
|
1480
1480
|
v *= s # 0 for 2-D root
|
|
1481
|
-
t0 = w
|
|
1482
|
-
t1 = _0_0 if g < 0 else (hypot_(u, w, v)
|
|
1481
|
+
t0 = w - _1_0
|
|
1482
|
+
t1 = _0_0 if g < 0 else (hypot_(u, w, v) - _1_0)
|
|
1483
1483
|
# assert t0 <= t1
|
|
1484
|
-
|
|
1485
|
-
for i in range(1, _TRIPS): # 47..65
|
|
1484
|
+
for i in range(1, _TRIPS): # 48..58
|
|
1486
1485
|
t = (t1 + t0) * _0_5
|
|
1487
1486
|
e = t1 - t0
|
|
1488
|
-
if
|
|
1487
|
+
if eps > e > -eps or _isin(t, t0, t1):
|
|
1489
1488
|
break
|
|
1490
1489
|
g = fsumf_(_N_1_0, # ~= _hypot2_1
|
|
1491
1490
|
_over02(u, t + r),
|
|
1492
|
-
_over02(w, t
|
|
1493
|
-
_over02(v, t + s) if v else _0_0)
|
|
1491
|
+
_over02(w, t + _1_0), (
|
|
1492
|
+
_over02(v, t + s) if v else _0_0))
|
|
1494
1493
|
if g > 0:
|
|
1495
1494
|
t0 = t
|
|
1496
1495
|
elif g < 0:
|
|
@@ -1527,7 +1526,7 @@ def _validate(a, b, c, d, T, x, y, z, val):
|
|
|
1527
1526
|
dot=e, eps=val)
|
|
1528
1527
|
|
|
1529
1528
|
|
|
1530
|
-
if __name__ ==
|
|
1529
|
+
if __name__ == _DMAIN_:
|
|
1531
1530
|
|
|
1532
1531
|
from pygeodesy import printf
|
|
1533
1532
|
from pygeodesy.interns import _COMMA_, _NL_, _NLATvar_
|
|
@@ -1540,6 +1539,10 @@ if __name__ == '__main__':
|
|
|
1540
1539
|
t = [NN] + Triaxials.toRepr(all=True, asorted=True).split(_NL_)
|
|
1541
1540
|
printf(_NLATvar_.join(i.strip(_COMMA_) for i in t))
|
|
1542
1541
|
|
|
1542
|
+
# % python3 -m pygeodesy.triaxials
|
|
1543
|
+
#
|
|
1544
|
+
# Bektas: height4(x=3909251.554667, y=3909165.750567, z=3170432.501602, h=999.999996)
|
|
1545
|
+
|
|
1543
1546
|
# **) MIT License
|
|
1544
1547
|
#
|
|
1545
1548
|
# Copyright (C) 2022-2025 -- mrJean1 at Gmail -- All Rights Reserved.
|
pygeodesy/units.py
CHANGED
|
@@ -6,11 +6,12 @@ basic C{float}, C{int} respectively C{str} to named units as L{Degrees},
|
|
|
6
6
|
L{Feet}, L{Meter}, L{Radians}, etc.
|
|
7
7
|
'''
|
|
8
8
|
|
|
9
|
-
from pygeodesy.basics import isscalar, issubclassof, signOf
|
|
9
|
+
from pygeodesy.basics import isscalar, issubclassof, signOf, typename
|
|
10
10
|
from pygeodesy.constants import EPS, EPS1, PI, PI2, PI_2, _umod_360, _0_0, \
|
|
11
11
|
_0_001, _0_5, INT0 # PYCHOK for .mgrs, .namedTuples
|
|
12
12
|
from pygeodesy.dms import F__F, F__F_, S_NUL, S_SEP, parseDMS, parseRad, _toDMS
|
|
13
13
|
from pygeodesy.errors import _AssertionError, TRFError, UnitError, _xattr, _xcallable
|
|
14
|
+
# from pygeodesy.internals import typename # from .basics
|
|
14
15
|
from pygeodesy.interns import NN, _azimuth_, _band_, _bearing_, _COMMASPACE_, \
|
|
15
16
|
_degrees_, _degrees2_, _distance_, _E_, _easting_, \
|
|
16
17
|
_epoch_, _EW_, _feet_, _height_, _lam_, _lat_, _LatLon_, \
|
|
@@ -27,7 +28,7 @@ from pygeodesy.unitsBase import Float, Int, _NamedUnit, Radius, Str, Fmt, fstr
|
|
|
27
28
|
from math import degrees, isnan, radians
|
|
28
29
|
|
|
29
30
|
__all__ = _ALL_LAZY.units
|
|
30
|
-
__version__ = '
|
|
31
|
+
__version__ = '25.04.14'
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
class Float_(Float):
|
|
@@ -860,8 +861,8 @@ def _std_repr(*Classes):
|
|
|
860
861
|
'''
|
|
861
862
|
from pygeodesy.internals import _getenv
|
|
862
863
|
for C in Classes:
|
|
863
|
-
if hasattr(C, _std_repr
|
|
864
|
-
env = 'PYGEODESY_%s_STD_REPR' % (C.
|
|
864
|
+
if hasattr(C, typename(_std_repr)): # PYCHOK del _std_repr
|
|
865
|
+
env = 'PYGEODESY_%s_STD_REPR' % (typename(C).upper(),)
|
|
865
866
|
if _getenv(env, _std_).lower() != _std_:
|
|
866
867
|
C._std_repr = False
|
|
867
868
|
|
pygeodesy/unitsBase.py
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
u'''Basic C{Float}, C{Int} and C{Str}ing units classes.
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
|
-
from pygeodesy.basics import isstr, issubclassof, _xsubclassof
|
|
7
|
+
from pygeodesy.basics import _isin, isstr, issubclassof, _xsubclassof, typename
|
|
8
8
|
from pygeodesy.errors import _IsnotError, _UnexpectedError, UnitError, _XError
|
|
9
|
+
# from pygeodesy.internals import typename # from .basics
|
|
9
10
|
from pygeodesy.interns import NN, _degrees_, _degrees2_, _invalid_, _meter_, \
|
|
10
11
|
_radians_, _radians2_, _radius_, _UNDER_, _units_, \
|
|
11
12
|
_std_ # PYCHOK used!
|
|
@@ -15,7 +16,7 @@ from pygeodesy.named import modulename, _Named, property_doc_
|
|
|
15
16
|
from pygeodesy.streprs import Fmt, fstr
|
|
16
17
|
|
|
17
18
|
__all__ = _ALL_LAZY.unitsBase
|
|
18
|
-
__version__ = '
|
|
19
|
+
__version__ = '25.04.14'
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class _NamedUnit(_Named):
|
|
@@ -49,7 +50,7 @@ class _NamedUnit(_Named):
|
|
|
49
50
|
elif name:
|
|
50
51
|
pass
|
|
51
52
|
elif name__ is not None:
|
|
52
|
-
name = name__
|
|
53
|
+
name = typename(name__)
|
|
53
54
|
return name, arg
|
|
54
55
|
|
|
55
56
|
@staticmethod # PYCHOK unused suffix
|
|
@@ -84,7 +85,7 @@ class _NamedUnit(_Named):
|
|
|
84
85
|
def std_repr(self, std):
|
|
85
86
|
'''Set the representation (C{True} or C{"std"} for standard).
|
|
86
87
|
'''
|
|
87
|
-
self._std_repr = std
|
|
88
|
+
self._std_repr = _isin(std, True, _std_)
|
|
88
89
|
|
|
89
90
|
def _toRepr(self, value):
|
|
90
91
|
'''(INTERNAL) Representation "<name> (<value>)" or "<classname>(<value>)".
|
pygeodesy/ups.py
CHANGED
|
@@ -28,7 +28,7 @@ from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
|
28
28
|
from pygeodesy.dms import degDMS, _neg, parseDMS2
|
|
29
29
|
from pygeodesy.errors import RangeError, _ValueError, _xkwds_pop2
|
|
30
30
|
from pygeodesy.fmath import hypot, hypot1, sqrt0
|
|
31
|
-
from pygeodesy.internals import
|
|
31
|
+
from pygeodesy.internals import _envPYGEODESY, _under
|
|
32
32
|
from pygeodesy.interns import NN, _COMMASPACE_, _inside_, _N_, \
|
|
33
33
|
_pole_, _range_, _S_, _scale0_, \
|
|
34
34
|
_SPACE_, _std_, _to_, _UTM_
|
|
@@ -49,9 +49,9 @@ from pygeodesy.utmupsBase import Fmt, _LLEB, _hemi, _parseUTMUPS5, _to4lldn, \
|
|
|
49
49
|
from math import fabs, radians, tan # as _tan
|
|
50
50
|
|
|
51
51
|
__all__ = _ALL_LAZY.ups
|
|
52
|
-
__version__ = '
|
|
52
|
+
__version__ = '25.04.14'
|
|
53
53
|
|
|
54
|
-
_BZ_UPS =
|
|
54
|
+
_BZ_UPS = _envPYGEODESY('UPS_POLES', _std_) == _std_
|
|
55
55
|
_Falsing = Meter(2000e3) # false easting and northing (C{meter})
|
|
56
56
|
_K0_UPS = Float(_K0_UPS= 0.994) # scale factor at central meridian
|
|
57
57
|
_K1_UPS = Float(_K1_UPS=_1_0) # rescale point scale factor
|
pygeodesy/utily.py
CHANGED
|
@@ -18,7 +18,7 @@ from pygeodesy.constants import EPS, EPS0, INF, NAN, PI, PI2, PI_2, R_M, \
|
|
|
18
18
|
_copysign_0_0, _float, _isfinite, isnan, isnear0, \
|
|
19
19
|
_over, _umod_360, _umod_PI2
|
|
20
20
|
from pygeodesy.errors import _ValueError, _xkwds, _ALL_LAZY, _MODS
|
|
21
|
-
from pygeodesy.internals import _passargs
|
|
21
|
+
from pygeodesy.internals import _passargs, typename
|
|
22
22
|
from pygeodesy.interns import _edge_, _radians_, _semi_circular_, _SPACE_
|
|
23
23
|
# from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .errors
|
|
24
24
|
from pygeodesy.units import Degrees, Degrees_, Feet, Float, Lam, Lamd, \
|
|
@@ -28,7 +28,7 @@ from math import acos, asin, atan2 as _atan2, cos, degrees, fabs, radians, \
|
|
|
28
28
|
sin, tan as _tan # pow
|
|
29
29
|
|
|
30
30
|
__all__ = _ALL_LAZY.utily
|
|
31
|
-
__version__ = '25.
|
|
31
|
+
__version__ = '25.04.14'
|
|
32
32
|
|
|
33
33
|
_G_DEG = _float( 400.0 / _360_0) # grades per degree
|
|
34
34
|
_G_RAD = _float( 400.0 / PI2) # grades per radian
|
|
@@ -1109,7 +1109,7 @@ def unrollPI(rad1, rad2, wrap=True):
|
|
|
1109
1109
|
def _valueError(where, x, raiser=True, **kwds):
|
|
1110
1110
|
'''(INTERNAL) Return a C{_ValueError} or C{None}.
|
|
1111
1111
|
'''
|
|
1112
|
-
t = _MODS.streprs.Fmt.PAREN(where
|
|
1112
|
+
t = _MODS.streprs.Fmt.PAREN(typename(where), x)
|
|
1113
1113
|
return _ValueError(t, **kwds) if raiser else None
|
|
1114
1114
|
|
|
1115
1115
|
|
|
@@ -1193,7 +1193,7 @@ class _Wrap(object):
|
|
|
1193
1193
|
lat, lon = ll.latlon
|
|
1194
1194
|
if fabs(lon) > _180_0 or fabs(lat) > _90_0:
|
|
1195
1195
|
_n = self.latlon
|
|
1196
|
-
ll = ll.copy(name=_n
|
|
1196
|
+
ll = ll.copy(name=typename(_n))
|
|
1197
1197
|
ll.latlon = _n(lat, lon)
|
|
1198
1198
|
return ll
|
|
1199
1199
|
|
pygeodesy/utmups.py
CHANGED
|
@@ -14,14 +14,14 @@ A pure Python implementation, partially transcoded from C++ class U{UTMUPS
|
|
|
14
14
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1UTMUPS.html>}
|
|
15
15
|
by I{Charles Karney}.
|
|
16
16
|
'''
|
|
17
|
-
|
|
17
|
+
from pygeodesy.basics import _isin, map1
|
|
18
18
|
# from pygeodesy.datums import _WGS84 # from .utmupsBase
|
|
19
19
|
from pygeodesy.errors import _IsnotError, RangeError, _ValueError, _xkwds_pop2
|
|
20
20
|
from pygeodesy.interns import NN, _easting_, _MGRS_, _northing_, _NS_, \
|
|
21
21
|
_outside_, _range_, _SPACE_, _UPS_, _UTM_
|
|
22
22
|
from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
|
|
23
23
|
from pygeodesy.named import modulename
|
|
24
|
-
from pygeodesy.namedTuples import UtmUps5Tuple, UtmUps8Tuple
|
|
24
|
+
from pygeodesy.namedTuples import UtmUps5Tuple, UtmUps8Tuple
|
|
25
25
|
# from pygeodesy.streprs import Fmt # from .utmupsBase
|
|
26
26
|
from pygeodesy.units import Northing, _100km
|
|
27
27
|
from pygeodesy.ups import parseUPS5, toUps8, Ups, UPSError, upsZoneBand5
|
|
@@ -31,7 +31,7 @@ from pygeodesy.utmupsBase import Fmt, _to4lldn, _to3zBhp, _UPS_ZONE, \
|
|
|
31
31
|
_UTMUPS_ZONE_MAX, _WGS84
|
|
32
32
|
|
|
33
33
|
__all__ = _ALL_LAZY.utmups
|
|
34
|
-
__version__ = '
|
|
34
|
+
__version__ = '25.04.14'
|
|
35
35
|
|
|
36
36
|
_MGRS_TILE = _100km # in .mgrs.Mgrs.tile
|
|
37
37
|
|
|
@@ -179,7 +179,7 @@ def UtmUps(zone, hemipole, easting, northing, band=NN, datum=_WGS84, falsed=True
|
|
|
179
179
|
<https://GeographicLib.SourceForge.io/C++/doc/classGeographicLib_1_1UTMUPS.html>}.
|
|
180
180
|
'''
|
|
181
181
|
z, B, hp = _to3zBhp(zone, band, hemipole=hemipole)
|
|
182
|
-
U = Ups if z
|
|
182
|
+
U = Ups if _isin(z, _UPS_ZONE, _UPS_ZONE_STR) else Utm
|
|
183
183
|
return U(z, hp, easting, northing, band=B, datum=datum, falsed=falsed, **name)
|
|
184
184
|
|
|
185
185
|
|
pygeodesy/utmupsBase.py
CHANGED
|
@@ -4,39 +4,44 @@
|
|
|
4
4
|
u'''(INTERNAL) Private class C{UtmUpsBase}, functions and constants
|
|
5
5
|
for modules L{epsg}, L{etm}, L{mgrs}, L{ups} and L{utm}.
|
|
6
6
|
'''
|
|
7
|
+
# make sure int/int division yields float quotient, see .basics
|
|
8
|
+
from __future__ import division as _; del _ # PYCHOK semicolon
|
|
7
9
|
|
|
8
|
-
from pygeodesy.basics import isint, isscalar, isstr,
|
|
9
|
-
|
|
10
|
+
from pygeodesy.basics import _copysign, _isin, isint, isscalar, isstr, \
|
|
11
|
+
neg_, _xinstanceof, _xsubclassof
|
|
10
12
|
from pygeodesy.constants import _float, _0_0, _0_5, _N_90_0, _180_0
|
|
11
13
|
from pygeodesy.datums import _ellipsoidal_datum, _WGS84
|
|
12
14
|
from pygeodesy.dms import degDMS, parseDMS2
|
|
13
15
|
from pygeodesy.ellipsoidalBase import LatLonEllipsoidalBase as _LLEB
|
|
14
16
|
from pygeodesy.errors import _or, ParseError, _parseX, _ValueError, \
|
|
15
17
|
_xattrs, _xkwds, _xkwds_not
|
|
18
|
+
# from pygeodesy.fsums import Fsum # _MODS
|
|
16
19
|
# from pygeodesy.internals import _name__, _under # from .named
|
|
17
|
-
from pygeodesy.interns import NN, _A_, _B_, _COMMA_, _Error_, \
|
|
18
|
-
|
|
19
|
-
_S_,
|
|
20
|
+
from pygeodesy.interns import NN, _A_, _B_, _COMMA_, _Error_, _gamma_, \
|
|
21
|
+
_n_a_, _not_, _N_, _NS_, _PLUS_, _scale_, \
|
|
22
|
+
_S_, _SPACE_, _Y_, _Z_
|
|
20
23
|
from pygeodesy.lazily import _ALL_DOCS, _ALL_LAZY, _ALL_MODS as _MODS
|
|
21
24
|
from pygeodesy.named import _name__, _NamedBase, _under
|
|
22
25
|
from pygeodesy.namedTuples import EasNor2Tuple, LatLonDatum5Tuple
|
|
23
26
|
from pygeodesy.props import deprecated_method, property_doc_, _update_all, \
|
|
24
27
|
deprecated_property_RO, Property_RO, property_RO
|
|
25
28
|
from pygeodesy.streprs import Fmt, fstr, _fstrENH2, _xzipairs
|
|
26
|
-
from pygeodesy.units import Band, Easting, Northing, Scalar, Zone
|
|
27
|
-
from pygeodesy.utily import _Wrap, wrap360
|
|
29
|
+
from pygeodesy.units import Band, Easting, Lat, Northing, Phi, Scalar, Zone
|
|
30
|
+
from pygeodesy.utily import atan1, _Wrap, wrap360
|
|
31
|
+
|
|
32
|
+
from math import cos, degrees, fabs, sin, tan # copysign as _copysign
|
|
28
33
|
|
|
29
34
|
__all__ = _ALL_LAZY.utmupsBase
|
|
30
|
-
__version__ = '
|
|
35
|
+
__version__ = '25.04.26'
|
|
31
36
|
|
|
32
37
|
_UPS_BANDS = _A_, _B_, _Y_, _Z_ # UPS polar bands SE, SW, NE, NW
|
|
33
38
|
# _UTM_BANDS = _MODS.utm._Bands
|
|
34
39
|
|
|
35
|
-
_UTM_LAT_MAX
|
|
36
|
-
_UTM_LAT_MIN
|
|
40
|
+
_UTM_LAT_MAX = _float( 84) # PYCHOK for export (C{degrees})
|
|
41
|
+
_UTM_LAT_MIN = _float(-80) # PYCHOK for export (C{degrees})
|
|
37
42
|
|
|
38
|
-
_UPS_LAT_MAX
|
|
39
|
-
_UPS_LAT_MIN
|
|
43
|
+
_UPS_LAT_MAX = _UTM_LAT_MAX - _0_5 # PYCHOK includes 30' UTM overlap
|
|
44
|
+
_UPS_LAT_MIN = _UTM_LAT_MIN + _0_5 # PYCHOK includes 30' UTM overlap
|
|
40
45
|
|
|
41
46
|
_UPS_LATS = {_A_: _N_90_0, _Y_: _UTM_LAT_MAX, # UPS band bottom latitudes,
|
|
42
47
|
_B_: _N_90_0, _Z_: _UTM_LAT_MAX} # PYCHOK see .Mgrs.bandLatitude
|
|
@@ -91,7 +96,7 @@ class UtmUpsBase(_NamedBase):
|
|
|
91
96
|
if band:
|
|
92
97
|
self._band1(band)
|
|
93
98
|
|
|
94
|
-
if
|
|
99
|
+
if not _isin(datum, None, self._datum):
|
|
95
100
|
self._datum = _ellipsoidal_datum(datum) # raiser=_datum_, name=band
|
|
96
101
|
|
|
97
102
|
if not falsed:
|
|
@@ -189,6 +194,67 @@ class UtmUpsBase(_NamedBase):
|
|
|
189
194
|
'''I{Must be overloaded}.'''
|
|
190
195
|
self._notOverloaded(self)
|
|
191
196
|
|
|
197
|
+
def _footpoint(self, y, lat0, makris):
|
|
198
|
+
'''(INTERNAL) Return the foot-point latitude in C{radians}.
|
|
199
|
+
'''
|
|
200
|
+
F = _MODS.fsums.Fsum
|
|
201
|
+
E = self.datum.ellipsoid
|
|
202
|
+
if y is None:
|
|
203
|
+
_, y = self.eastingnorthing2(falsed=False)
|
|
204
|
+
B = F(E.Llat(lat0), y)
|
|
205
|
+
if E.isSpherical:
|
|
206
|
+
r = B.fover(E.a) # == E.b
|
|
207
|
+
|
|
208
|
+
elif makris:
|
|
209
|
+
b = B.fover(E.b)
|
|
210
|
+
r = fabs(b)
|
|
211
|
+
if r:
|
|
212
|
+
e2 = E.e22 # E.e22abs?
|
|
213
|
+
e4 = E.e4
|
|
214
|
+
|
|
215
|
+
e1 = F(-1, e2 / 4, -11 / 64 * e4).as_iscalar
|
|
216
|
+
e2 = F( e2 / 8, -13 / 128 * e4).as_iscalar
|
|
217
|
+
e4 *= cos(r)**2 / 8
|
|
218
|
+
|
|
219
|
+
s = sin(r * 2)
|
|
220
|
+
r = -r
|
|
221
|
+
U = F(e1 * r, e2 * s, e4 * r, e4 / 8 * 5 * s**2)
|
|
222
|
+
r = _copysign(atan1(E.a * tan(float(U)) / E.b), b)
|
|
223
|
+
|
|
224
|
+
# elif clins: # APRIL-ZJU/clins/include/utils/gps_convert_utils.h
|
|
225
|
+
# n = E.n
|
|
226
|
+
# n2 = n**2
|
|
227
|
+
# n3 = n**3
|
|
228
|
+
# n4 = n**4
|
|
229
|
+
# n5 = n**5
|
|
230
|
+
# A = F(1, n2 / 4, n4 / 64).fmul((E.a + E.b) / 2)
|
|
231
|
+
# r = B.fover(A)
|
|
232
|
+
# R = F(r)
|
|
233
|
+
# if clins: # FootpointLatitude, GPS-Theory-Practice, 1994
|
|
234
|
+
# R += F(3 / 2 * n, -27 / 32 * n3, 269 / 512 * n5).fmul(sin(r * 2))
|
|
235
|
+
# R += F( 21 / 16 * n2, -55 / 32 * n4).fmul(sin(r * 4))
|
|
236
|
+
# R += F( 151 / 96 * n3, -417 / 128 * n5).fmul(sin(r * 6))
|
|
237
|
+
# R += (1097 / 512 * n4) * sin(r * 8)
|
|
238
|
+
# else: # GPS-Theory-Practice, 1992, page 234-235
|
|
239
|
+
# R += F(-3 / 2 * n, 9 / 16 * n3, -3 / 32 * n5).fmul(sin(r * 2))
|
|
240
|
+
# R += F( 15 / 16 * n2, -15 / 32 * n4).fmul(sin(r * 4))
|
|
241
|
+
# R += F( -35 / 48 * n3, 105 / 256 * n4).fmul(sin(r * 6)) # n5?
|
|
242
|
+
# r = float(R)
|
|
243
|
+
|
|
244
|
+
else: # PyGeodetics/src/geodetics/footpoint_latitude.py
|
|
245
|
+
f = E.f
|
|
246
|
+
f2 = f**2
|
|
247
|
+
f3 = f**3
|
|
248
|
+
B0 = F(1, -f / 2, f2 / 16, f3 / 32).fmul(E.a)
|
|
249
|
+
r = B.fover(B0)
|
|
250
|
+
R = F(r)
|
|
251
|
+
R += F(3 / 4 * f, 3 / 8 * f2, 21 / 256 * f3).fmul(sin(r * 2))
|
|
252
|
+
R += F( 21 / 64 * f2, 21 / 64 * f3).fmul(sin(r * 4))
|
|
253
|
+
R += (151 / 768 * f3) * sin(r * 6)
|
|
254
|
+
r = float(R)
|
|
255
|
+
|
|
256
|
+
return r
|
|
257
|
+
|
|
192
258
|
@Property_RO
|
|
193
259
|
def gamma(self):
|
|
194
260
|
'''Get the meridian convergence (C{degrees}) or C{None}
|
|
@@ -204,6 +270,23 @@ class UtmUpsBase(_NamedBase):
|
|
|
204
270
|
self._toLLEB()
|
|
205
271
|
return self._hemisphere
|
|
206
272
|
|
|
273
|
+
def latFootPoint(self, northing=None, lat0=0, makris=False):
|
|
274
|
+
'''Compute the foot-point latitude in C{degrees}.
|
|
275
|
+
|
|
276
|
+
@arg northing: Northing (C{meter}, same units this ellipsoid's axes),
|
|
277
|
+
overriding this northing, I{unfalsed}.
|
|
278
|
+
@kwarg lat0: Geodetic latitude of the meridian's origin (C{degrees}).
|
|
279
|
+
@kwarg makris: If C{True}, use C{Makris}' formula, otherwise C{PyGeodetics}'.
|
|
280
|
+
|
|
281
|
+
@return: Foot-point latitude (C{degrees}).
|
|
282
|
+
|
|
283
|
+
@see: U{PyGeodetics<https://GitHub.com/paarnes/pygeodetics>}, U{FootpointLatitude
|
|
284
|
+
<https://GitHub.com/APRIL-ZJU/clins/blob/master/include/utils/gps_convert_utils.h#L143>},
|
|
285
|
+
U{Makris<https://www.TandFonline.com/doi/abs/10.1179/sre.1982.26.205.345>} and
|
|
286
|
+
U{Geomatics' Mercator, page 60<https://Geomatics.CC/legacy-files/mercator.pdf>}.
|
|
287
|
+
'''
|
|
288
|
+
return Lat(FootPoint=degrees(self._footpoint(northing, lat0, makris)))
|
|
289
|
+
|
|
207
290
|
def _latlon5(self, LatLon, **LatLon_kwds):
|
|
208
291
|
'''(INTERNAL) Get cached C{._toLLEB} as B{C{LatLon}} instance.
|
|
209
292
|
'''
|
|
@@ -255,6 +338,15 @@ class UtmUpsBase(_NamedBase):
|
|
|
255
338
|
'''
|
|
256
339
|
return self._northing
|
|
257
340
|
|
|
341
|
+
def phiFootPoint(self, northing=None, lat0=0, makris=False):
|
|
342
|
+
'''Compute the foot-point latitude in C{radians}.
|
|
343
|
+
|
|
344
|
+
@return: Foot-point latitude (C{radians}).
|
|
345
|
+
|
|
346
|
+
@see: Method L{latFootPoint<UtmUpsBase.latFootPoint>} for further details.
|
|
347
|
+
'''
|
|
348
|
+
return Phi(FootPoint=self._footpoint(northing, lat0, makris))
|
|
349
|
+
|
|
258
350
|
@Property_RO
|
|
259
351
|
def scale(self):
|
|
260
352
|
'''Get the grid scale (C{float}) or C{None}.
|
|
@@ -302,9 +394,9 @@ class UtmUpsBase(_NamedBase):
|
|
|
302
394
|
@note: If not specified, the I{latitudinal} C{band} is computed from
|
|
303
395
|
the (geodetic) latitude and the C{datum}.
|
|
304
396
|
'''
|
|
305
|
-
return self.
|
|
306
|
-
|
|
307
|
-
|
|
397
|
+
return self._mgrs_lowerleft if center is True else (
|
|
398
|
+
_toMgrs(_lowerleft(self, center)) if center else
|
|
399
|
+
self._mgrs) # PYCHOK indent
|
|
308
400
|
|
|
309
401
|
def _toRepr(self, fmt, B, cs, prec, sep): # PYCHOK expected
|
|
310
402
|
'''(INTERNAL) Return a representation for this ETM/UTM/UPS coordinate.
|
|
@@ -349,8 +441,8 @@ def _lowerleft(utmups, center): # in .ellipsoidalBase._lowerleft
|
|
|
349
441
|
t = c * 2
|
|
350
442
|
e = int(utmups.easting % t)
|
|
351
443
|
n = int(utmups.northing % t)
|
|
352
|
-
if (e == c and n
|
|
353
|
-
(n == c and e
|
|
444
|
+
if (e == c and _isin(n, c, c - 1)) or \
|
|
445
|
+
(n == c and _isin(e, c, c - 1)):
|
|
354
446
|
break
|
|
355
447
|
else:
|
|
356
448
|
return utmups # unchanged
|
pygeodesy/vector2d.py
CHANGED
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
u'''2- or 3-D vectorial functions L{circin6}, L{circum3}, L{circum4_},
|
|
5
|
-
L{iscolinearWith}, L{meeus2}, L{nearestOn}, L{radii11}, L{soddy4}
|
|
6
|
-
L{trilaterate2d2}.
|
|
5
|
+
L{iscolinearWith}, L{meeus2}, L{nearestOn}, L{radii11}, L{soddy4},
|
|
6
|
+
L{triaxum5} and L{trilaterate2d2}.
|
|
7
|
+
|
|
8
|
+
@note: Functions L{circin6}, L{circum3}, L{circum4_}, L{soddy4} and
|
|
9
|
+
L{triaxum5} require U{numpyhttps://PyPI.org/project/numpy>}
|
|
10
|
+
version 1.10 or newer to be installed.
|
|
7
11
|
'''
|
|
8
12
|
|
|
9
|
-
from pygeodesy.basics import len2, map2, _xnumpy
|
|
13
|
+
from pygeodesy.basics import len2, map2, _xnumpy, typename
|
|
10
14
|
from pygeodesy.constants import EPS, EPS0, EPS02, EPS4, INF, INT0, \
|
|
11
15
|
_EPS4e8, isnear0, _0_0, _0_25, _0_5, _N_0_5, \
|
|
12
16
|
_1_0, _1_0_1T, _N_1_0, _2_0, _N_2_0, _4_0
|
|
13
17
|
from pygeodesy.errors import _and, _AssertionError, IntersectionError, NumPyError, \
|
|
14
18
|
PointsError, TriangleError, _xError, _xkwds
|
|
15
|
-
from pygeodesy.fmath import fabs, fdot, fdot_, hypot, hypot2_, sqrt
|
|
19
|
+
from pygeodesy.fmath import fabs, fdot, Fdot_, fdot_, hypot, hypot2_, sqrt
|
|
16
20
|
from pygeodesy.fsums import _Fsumf_, fsumf_, fsum1f_
|
|
21
|
+
# from pygeodesy.internals import typename # from .basics
|
|
17
22
|
from pygeodesy.interns import NN, _a_, _and_, _b_, _c_, _center_, _coincident_, \
|
|
18
23
|
_colinear_, _COMMASPACE_, _concentric_, _few_, \
|
|
19
24
|
_intersection_, _invalid_, _near_, _no_, _of_, \
|
|
@@ -31,7 +36,7 @@ from contextlib import contextmanager
|
|
|
31
36
|
# from math import fabs, sqrt # from .fmath
|
|
32
37
|
|
|
33
38
|
__all__ = _ALL_LAZY.vector2d
|
|
34
|
-
__version__ = '
|
|
39
|
+
__version__ = '25.04.30'
|
|
35
40
|
|
|
36
41
|
_cA_ = 'cA'
|
|
37
42
|
_cB_ = 'cB'
|
|
@@ -184,7 +189,7 @@ def _circin6(point1, point2, point3, eps=EPS4, useZ=True, dLL3=False, **Vector_k
|
|
|
184
189
|
|
|
185
190
|
r = t.rIn
|
|
186
191
|
c, d = _tricenter3d2(c1, r, c2, r, c3, r, eps=eps, useZ=useZ, dLL3=dLL3,
|
|
187
|
-
**_xkwds(Vector_kwds, Vector=V, name=circin6
|
|
192
|
+
**_xkwds(Vector_kwds, Vector=V, name=typename(circin6)))
|
|
188
193
|
return Circin6Tuple(r, c, d, cA, cB, cC)
|
|
189
194
|
|
|
190
195
|
|
|
@@ -236,7 +241,7 @@ def _circum3(p1, point2, point3, circum=True, eps=EPS4, useZ=True, dLL3=False,
|
|
|
236
241
|
r, d, p2, p3 = _meeus4(p1, point2, point3, circum=circum, useZ=useZ,
|
|
237
242
|
clas=clas, **clas_kwds)
|
|
238
243
|
if d is None: # Meeus' Type II or circum=True
|
|
239
|
-
kwds = _xkwds(clas_kwds, eps=eps, Vector=clas, name=circum3
|
|
244
|
+
kwds = _xkwds(clas_kwds, eps=eps, Vector=clas, name=typename(circum3))
|
|
240
245
|
c, d = _tricenter3d2(p1, r, p2, r, p3, r, useZ=useZ, dLL3=dLL3, **kwds)
|
|
241
246
|
else: # Meeus' Type I
|
|
242
247
|
c, d = d, None
|
|
@@ -386,7 +391,7 @@ def _meeus4(A, point2, point3, circum=False, useZ=True, clas=None, **clas_kwds):
|
|
|
386
391
|
r = sqrt(a * _0_25) if a > EPS02 else INT0
|
|
387
392
|
t = B.plus(C).times(_0_5) # Meeus' Type I
|
|
388
393
|
if clas is not None:
|
|
389
|
-
t = clas(t.x, t.y, t.z, **_xkwds(clas_kwds, name=meeus2
|
|
394
|
+
t = clas(t.x, t.y, t.z, **_xkwds(clas_kwds, name=typename(meeus2)))
|
|
390
395
|
return r, t, p2, p3
|
|
391
396
|
|
|
392
397
|
|
|
@@ -410,6 +415,8 @@ class _numpy(object): # see also .formy._idllmn6, .geodesicw._wargs, .latlonBas
|
|
|
410
415
|
|
|
411
416
|
@Property_RO
|
|
412
417
|
def array(self):
|
|
418
|
+
'''Get U{numpy.array<https://NumPy.org/doc/2.2/reference/generated/numpy.array.html#numpy.array>}.
|
|
419
|
+
'''
|
|
413
420
|
return self.np.array
|
|
414
421
|
|
|
415
422
|
def least_squares3(self, A, b):
|
|
@@ -595,7 +602,7 @@ def soddy4(point1, point2, point3, eps=EPS4, useZ=True):
|
|
|
595
602
|
c, d = _tricenter3d2(p1, t.rA + r,
|
|
596
603
|
p2, t.rB + r,
|
|
597
604
|
p3, t.rC + r, eps=eps, useZ=useZ,
|
|
598
|
-
Vector=point1.classof, name=soddy4
|
|
605
|
+
Vector=point1.classof, name=typename(soddy4))
|
|
599
606
|
return Soddy4Tuple(r, c, d, t.roS)
|
|
600
607
|
|
|
601
608
|
|
|
@@ -748,8 +755,8 @@ def _trilaterate2d2(x1, y1, radius1, x2, y2, radius2, x3, y3, radius3,
|
|
|
748
755
|
raise IntersectionError(_and(_astr(x1=x1, y1=y1, radius1=r1),
|
|
749
756
|
_astr(x2=x2, y2=y2, radius2=r2),
|
|
750
757
|
_astr(x3=x3, y3=y3, radius3=r3)), txt=t)
|
|
751
|
-
t = Vector2Tuple(
|
|
752
|
-
|
|
758
|
+
t = Vector2Tuple(Fdot_(c, e, -b, f).fover(q),
|
|
759
|
+
Fdot_(a, f, -c, d).fover(q), name=typename(trilaterate2d2))
|
|
753
760
|
|
|
754
761
|
if eps and eps > 0: # check distances to center vs radius
|
|
755
762
|
for x, y, r in ((x1, y1, r1), (x2, y2, r2), (x3, y3, r3)):
|
|
@@ -784,7 +791,7 @@ def _trilaterate3d2(c1, r1, c2, r2, c3, r3, eps=EPS4, coin=False, # MCCABE 13
|
|
|
784
791
|
def _N3(t01, x, z):
|
|
785
792
|
# compute x, y and z and return as B{C{clas}} or B{C{Vector}}
|
|
786
793
|
v = x.plus(z.times(t01))
|
|
787
|
-
n = trilaterate3d2
|
|
794
|
+
n = typename(trilaterate3d2)
|
|
788
795
|
return _nVc(v, **_xkwds(clas_Vector_and_kwds, name=n))
|
|
789
796
|
|
|
790
797
|
c2 = _otherV3d(center2=c2, NN_OK=False)
|
|
@@ -828,7 +835,7 @@ def _trilaterate3d2(c1, r1, c2, r2, c3, r3, eps=EPS4, coin=False, # MCCABE 13
|
|
|
828
835
|
r = repr(r1) if r1 == r2 == r3 else _reprs(r1, r2, r3)
|
|
829
836
|
t = _SPACE_(t, _of_, _reprs(c1, c2, c3), _with_, _radius_, r)
|
|
830
837
|
elif Z is None:
|
|
831
|
-
t = _COMMASPACE_(t, _no_(_numpy.null_space2
|
|
838
|
+
t = _COMMASPACE_(t, _no_(typename(_numpy.null_space2)))
|
|
832
839
|
return t
|
|
833
840
|
|
|
834
841
|
# coincident, concentric, colinear, too distant, no intersection:
|