pygeodesy 26.1.16__py2.py3-none-any.whl → 26.2.2__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 CHANGED
@@ -626,7 +626,7 @@ else:
626
626
 
627
627
  from pygeodesy.internals import _version2, _DOT_ # noqa: E402
628
628
  # from pygeodesy.interns import _DOT_ # from .internals
629
- __version__ = '26.01.16'
629
+ __version__ = '26.02.02'
630
630
  # see setup.py for similar logic
631
631
  version = _DOT_(*_version2(__version__, n=3))
632
632
 
@@ -26,7 +26,7 @@ from pygeodesy.utily import atan1, atan2 # from .auxilats.auxily
26
26
  from math import cos, sin, sqrt
27
27
 
28
28
  __all__ = ()
29
- __version__ = '25.05.12'
29
+ __version__ = '26.01.20'
30
30
 
31
31
 
32
32
  class AuxDLat(AuxLat):
@@ -107,10 +107,9 @@ class AuxDLat(AuxLat):
107
107
  t2 = _1_0 + t**2
108
108
  Dt *= _2_0 / t2
109
109
  sk2 = (d * Dt)**2 * k2
110
- d2 = _1_0 - sk2
111
110
  c2 = ((_1_0 - t) * (_1_0 + t) / t2)**2 if t else _1_0
112
111
  # E(z)/sin(z)
113
- Dt *= _Ef._RFRD(c2, d2, _1_0, sk2) - k2 * sx * sy
112
+ Dt *= _Ef._fRF3RD(c2, _1_0, sk2) - k2 * sx * sy
114
113
  return Dt
115
114
 
116
115
  def DIsometric(self, Phi1, Phi2):
@@ -48,7 +48,7 @@ except ImportError: # Python 3.11-
48
48
  return pow(_2_0, x)
49
49
 
50
50
  __all__ = ()
51
- __version__ = '25.05.12'
51
+ __version__ = '26.01.20'
52
52
 
53
53
  _TRIPS = 1024 # XXX 2 or 3?
54
54
 
@@ -621,19 +621,18 @@ class AuxLat(AuxAngle):
621
621
  ka, kb = kb, ka
622
622
  ka1, kb1 = kb1, ka1
623
623
  sb, cb = cb, sb
624
- # now a, b = larger/smaller semiaxis
625
- # Beta measured from larger semiaxis
624
+ # now a, b = larger/smaller semi-axis
625
+ # Beta measured from larger semi-axis
626
626
  # kb, ka = modulus-squared for distance from Beta = 0, pi/2
627
627
  # NB kb <= 0; 0 <= ka <= 1
628
628
  # sa = b*E(Beta, sqrt(kb))
629
629
  # sb = a*E(Beta',sqrt(ka))
630
630
  # 1 - ka * (1 - sb2) = 1 - ka + ka*sb2
631
- sb2 = sb**2
632
- cb2 = cb**2
633
- da2 = ka1 + ka * sb2
634
- db2 = _1_0 - kb * sb2
631
+ sb2 = sb**2
632
+ cb2 = cb**2
633
+ da2 = ka1 + ka * sb2
635
634
  # DLMF Eq. 19.25.9
636
- my = b * sb * _Ef._RFRD(cb2, db2, _1_0, kb * sb2)
635
+ my = b * sb * _Ef._fRF3RD(cb2, _1_0, kb * sb2)
637
636
  # DLMF Eq. 19.25.10 with complementary angles
638
637
  mx = a * cb * (_Ef.fRF(sb2, da2, _1_0) * ka1 +
639
638
  ka * cb2 * _Ef.fRD(sb2, _1_0, da2, _3_0) * ka1 +
pygeodesy/elliptic.py CHANGED
@@ -102,7 +102,7 @@ from math import asin, asinh, atan, ceil, cosh, fabs, floor, radians, \
102
102
  # import operator as _operator # from .fmath
103
103
 
104
104
  __all__ = _ALL_LAZY.elliptic
105
- __version__ = '26.01.16'
105
+ __version__ = '26.01.20'
106
106
 
107
107
  _TolRD = zqrt(EPS * 0.002)
108
108
  _TolRF = zqrt(EPS * 0.030)
@@ -1212,6 +1212,17 @@ class Elliptic(_Named):
1212
1212
  except Exception as X:
1213
1213
  raise _ellipticError(Elliptic.fRF, x, y, z, cause=X)
1214
1214
 
1215
+ @staticmethod
1216
+ def _fRF3RD(x, z, m): # in .auxilats.AuxDLat.DE, -.AuxLat.Rectifying
1217
+ y = _1_0 - m
1218
+ try: # float(RF(x, y, z) - RD(x, y, z, 3 / m))
1219
+ R = _RF3(x, y, z)
1220
+ if m:
1221
+ R -= _RD(x, y, z, _3_0 / m)
1222
+ except Exception as X:
1223
+ raise _ellipticError(Elliptic._fRF3RD, x, y, z, m, cause=X)
1224
+ return float(R)
1225
+
1215
1226
  @staticmethod
1216
1227
  def fRG(x, y, z=0):
1217
1228
  '''Symmetric or complete symmetric integral of the second kind
@@ -1246,16 +1257,6 @@ class Elliptic(_Named):
1246
1257
  except Exception as X:
1247
1258
  raise _ellipticError(Elliptic.fRJ, x, y, z, p, cause=X)
1248
1259
 
1249
- @staticmethod
1250
- def _RFRD(x, y, z, m): # in .auxilats.AuxDLat.DE, -.AuxLat.Rectifying
1251
- try: # float(RF(x, y, z) - RD(x, y, z, 3 / m))
1252
- R = _RF3(x, y, z)
1253
- if m:
1254
- R -= _RD(x, y, z, _3_0 / m)
1255
- except Exception as X:
1256
- raise _ellipticError(Elliptic._RFRD, x, y, z, m, cause=X)
1257
- return float(R)
1258
-
1259
1260
  _allPropertiesOf_n(16, Elliptic) # PYCHOK assert, see Elliptic.reset
1260
1261
 
1261
1262
 
pygeodesy/fsums.py CHANGED
@@ -52,9 +52,8 @@ from pygeodesy.interns import NN, _arg_, _COMMASPACE_, _DMAIN_, _DOT_, _from_, \
52
52
  # from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS # from .named
53
53
  from pygeodesy.named import _name__, _name2__, _Named, _NamedTuple, \
54
54
  _NotImplemented, _ALL_LAZY, _MODS
55
- from pygeodesy.props import _allPropertiesOf_n, deprecated_method, \
56
- deprecated_property_RO, Property, \
57
- Property_RO, property_RO
55
+ from pygeodesy.props import _allPropertiesOf_n, deprecated_method, Property, \
56
+ deprecated_property_RO, Property_RO, property_RO
58
57
  from pygeodesy.streprs import Fmt, fstr, unstr
59
58
  # from pygeodesy.units import Float, Int # from .constants
60
59
 
@@ -62,7 +61,7 @@ from math import fabs, isinf, isnan, \
62
61
  ceil as _ceil, floor as _floor # PYCHOK used! .ltp
63
62
 
64
63
  __all__ = _ALL_LAZY.fsums
65
- __version__ = '26.01.16'
64
+ __version__ = '26.02.02'
66
65
 
67
66
  from pygeodesy.interns import (
68
67
  _PLUS_ as _add_op_, # in .auxilats.auxAngle
@@ -197,8 +196,7 @@ except ImportError: # PYCHOK DSPACE! Python 3.12-
197
196
  _2FACTOR = pow(2, (MANT_DIG + 1) // 2) + _1_0 # 134217729 if MANT_DIG == 53
198
197
 
199
198
  def _2split3(x):
200
- # Split U{Algorithm 3.2
201
- # <https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
199
+ # Split U{Algorithm 3.2<https://www.TUHH.De/ti3/paper/rump/OgRuOi05.pdf>}
202
200
  a = c = x * _2FACTOR
203
201
  a -= c - x
204
202
  b = x - a
@@ -326,13 +324,31 @@ def nonfiniterrors(raiser=None):
326
324
  _xkwds_get1(d, _isfine=_isfinite) is _isfinite) if d else True
327
325
 
328
326
 
329
- def _1primed(xs): # in .fmath
330
- '''(INTERNAL) 1-Primed summation of iterable C{xs}
327
+ # def _nsum(xs):
328
+ # '''(INTERNAL) U{Neumaier summation
329
+ # <https://StackOverflow.com/questions/78633770/can-neumaier-summation-be-sped-up>},
330
+ # see IV. Verbessertes Kahan-Babuška-Verfahren.
331
+ # '''
332
+ # s = r = _0_0
333
+ # for x in map(float, xs):
334
+ # t = s + x
335
+ # if fabs(x) <= fabs(s):
336
+ # r += (s - t) + x
337
+ # else:
338
+ # r += (x - t) + s
339
+ # s = t
340
+ # return s + r
341
+
342
+
343
+ def _1primed(xs, *ys): # in .fmath
344
+ '''(INTERNAL) 1-Primed summation of iterable C{xs} less any C{ys}
331
345
  items, all I{known} to be C{scalar}.
332
346
  '''
333
347
  yield _1_0
334
348
  for x in xs:
335
349
  yield x
350
+ for y in ys:
351
+ yield -y
336
352
  yield _N_1_0
337
353
 
338
354
 
@@ -485,10 +501,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
485
501
  i.e. any C{type} having method C{__float__}.
486
502
 
487
503
  @note: Handling of I{non-finites} as C{inf}, C{INF}, C{NINF}, C{nan} and C{NAN} is
488
- determined by function L{nonfiniterrors<fsums.nonfiniterrors>} for the default
489
- or by method L{nonfinites<Fsum.nonfinites>} for individual C{Fsum} instances,
490
- overruling the default. For backward compatibility, I{non-finites} raise
491
- exceptions by default.
504
+ determined globally by function L{nonfiniterrors<fsums.nonfiniterrors>} or
505
+ by method L{nonfinites<Fsum.nonfinites>} for individual C{Fsum} instances,
506
+ overruling the global setting. For backward compatibility, I{non-finites}
507
+ raise exceptions by default.
492
508
 
493
509
  @see: U{Hettinger<https://GitHub.com/ActiveState/code/tree/master/recipes/Python/
494
510
  393090_Binary_floating_point_summatiaccurate_full/recipe-393090.py>},
@@ -1333,11 +1349,10 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
1333
1349
  H._fadd(c, up=False)
1334
1350
  else: # x == 0
1335
1351
  H = cs[0] if n else 0
1336
- self._fadd(H)
1352
+ return self._fadd(H)
1337
1353
  except Exception as X:
1338
1354
  t = unstr(where, x, *cs, _ELLIPSIS=4, incx=incx)
1339
1355
  raise self._ErrorX(X, _add_op_, t)
1340
- return self
1341
1356
 
1342
1357
  def _finite(self, other, op=None):
1343
1358
  '''(INTERNAL) Return B{C{other}} if C{finite}.
@@ -2286,7 +2301,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
2286
2301
  # assert isscalar(s) and isscalar(x)
2287
2302
  return self._pow_2_3(s, x, other, op, **raiser_RESIDUAL)
2288
2303
 
2289
- def _ps_acc(self, ps, xs, up=True, **unused):
2304
+ def _ps_acc(self, ps, xs, up=True, **unused): # in .geoids._Dotf and ._Hornerf
2290
2305
  '''(INTERNAL) Accumulate C{xs} known scalars into list C{ps}.
2291
2306
  '''
2292
2307
  n = 0
@@ -2356,15 +2371,7 @@ class Fsum(_Named): # sync __methods__ with .vector3dBase.Vector3dBase, .fstats
2356
2371
  def _ps_1sum(self, *less):
2357
2372
  '''(INTERNAL) Return the partials sum, 1-primed C{less} some scalars.
2358
2373
  '''
2359
- def _1psls(ps, ls):
2360
- yield _1_0
2361
- for p in ps:
2362
- yield p
2363
- for p in ls:
2364
- yield -p
2365
- yield _N_1_0
2366
-
2367
- return _fsum(_1psls(self._ps, less))
2374
+ return _fsum(_1primed(self._ps, *less))
2368
2375
 
2369
2376
  def _raiser(self, r, s, raiser=True, **RESIDUAL):
2370
2377
  '''(INTERNAL) Does ratio C{r / s} exceed the RESIDUAL threshold
@@ -2726,7 +2733,7 @@ try:
2726
2733
  except ImportError:
2727
2734
  _sum = sum
2728
2735
 
2729
- def _fsum(xs): # in .elliptic
2736
+ def _fsum(xs): # in .elliptic, .geoids
2730
2737
  '''(INTERNAL) Precision summation, Python 2.5-.
2731
2738
  '''
2732
2739
  F = Fsum(name=_fsum.name, f2product=False, nonfinites=True)
@@ -2867,8 +2874,11 @@ if __name__ == _DMAIN_:
2867
2874
  # copied from Hettinger, see L{Fsum} reference
2868
2875
  from pygeodesy import frandoms, printf
2869
2876
 
2877
+ # printf(typename(_sum), end=_COMMASPACE_)
2870
2878
  printf(typename(_fsum), end=_COMMASPACE_)
2871
2879
  printf(typename(_psum), end=_COMMASPACE_)
2880
+ printf(len(Fsum.__dict__), end=_COMMASPACE_)
2881
+ # printf(len(globals()), end=_COMMASPACE_)
2872
2882
 
2873
2883
  F = Fsum()
2874
2884
  if F.is_math_fsum():
pygeodesy/geoids.py CHANGED
@@ -89,18 +89,17 @@ courtesy of SBFRF.
89
89
  # make sure int/int division yields float quotient, see .basics
90
90
  from __future__ import division as _; del _ # noqa: E702 ;
91
91
 
92
- from pygeodesy.basics import _isin, len2, min2, isodd, _splituple, \
93
- ub2str as _ub2str
92
+ from pygeodesy.basics import _isin, len2, min2, isodd, _splituple
94
93
  from pygeodesy.constants import EPS, _float as _F, _1_0, _N_90_0, _180_0, \
95
94
  _N_180_0, _360_0
96
95
  from pygeodesy.datums import Datums, _ellipsoidal_datum, _WGS84
97
96
  # from pygeodesy.dms import parseDMS2 # _MODS
98
97
  from pygeodesy.errors import _incompatible, LenError, RangeError, _SciPyIssue, \
99
98
  _xkwds_pop2
100
- from pygeodesy.fmath import favg, Fdot, fdot, Fhorner, frange
99
+ from pygeodesy.fmath import favg, frange, Fsum
101
100
  # from pygoedesy.formy import heightOrthometric # _MODS
102
- from pygeodesy.heights import _as_llis2, _ascalar, _HeightBase, HeightError, \
103
- _Wrap
101
+ # from pygeodesy.fsums import Fsum # from .fmath
102
+ from pygeodesy.heights import _as_llis2, _ascalar, _HeightBase, HeightError, _Wrap
104
103
  # from pygeodesy.internals import typename, _version2 # _MODS
105
104
  from pygeodesy.interns import NN, _COLONSPACE_, _COMMASPACE_, _DMAIN_, _E_, \
106
105
  _height_, _in_, _kind_, _lat_, _lon_, _mean_, _N_, \
@@ -115,8 +114,8 @@ from pygeodesy.units import Height, Int_, Lat, Lon
115
114
  # from pygeodesy.utily import _Wrap # from .heights
116
115
 
117
116
  from math import floor as _floor
118
- # from os import SEEK_CUR, SEEK_SET # _MODS
119
- # import os.path # _MODS
117
+ # import os as _os # _MODS
118
+ # import os.path # _os.path
120
119
  from struct import calcsize as _calcsize, unpack as _unpack
121
120
  try:
122
121
  from StringIO import StringIO as _BytesIO # reads bytes
@@ -124,9 +123,10 @@ try:
124
123
 
125
124
  except ImportError: # Python 3+
126
125
  from io import BytesIO as _BytesIO # PYCHOK expected
126
+ from pygeodesy.basics import ub2str as _ub2str
127
127
 
128
128
  __all__ = _ALL_LAZY.geoids
129
- __version__ = '25.09.26'
129
+ __version__ = '26.02.02'
130
130
 
131
131
  _assert_ = 'assert'
132
132
  _bHASH_ = b'#'
@@ -135,9 +135,50 @@ _format_ = '%s %r'
135
135
  _header_ = 'header'
136
136
  _intCs = {} # cache int value, del below
137
137
  _lli_ = 'lli'
138
+ _os = _MODS.os
138
139
  _rb_ = 'rb'
139
140
  _supported_ = 'supported'
140
141
 
142
+ if __debug__:
143
+ from pygeodesy.fmath import Fdot as _Dotf, Fhorner as _Hornerf
144
+
145
+ else: # -OO ... runs GeoidKarney 8+X faster (w/o Fwelford)
146
+ from pygeodesy.fsums import _fsum
147
+ from operator import mul as _mul
148
+
149
+ class _GKsum(Fsum): # for GeoidKarney only
150
+
151
+ def __iadd__(self, other):
152
+ xs = other._ps if isinstance(other, _GKsum) else (other,)
153
+ self._ps_acc(self._ps, xs, up=False)
154
+ return self
155
+
156
+ def __imul__(self, x):
157
+ self._ps[:] = (x * p for p in self._ps)
158
+ return self
159
+
160
+ fmul = __imul__ # like .fsums.Fsum
161
+
162
+ def fsum(self): # PYCHOK signature
163
+ return _fsum(self._ps)
164
+
165
+ class _Dotf(_GKsum): # PYCHOK redef
166
+ '''Fast precision dot product M{sum(a[i] * b[i] for i=0..len(a))}
167
+ but for C{float} C{a} and C{b} only.
168
+ '''
169
+ def __init__(self, a, *b):
170
+ self._ps = self._ps_acc([], map(_mul, a, b), up=False)
171
+
172
+ class _Hornerf(_GKsum): # PYCHOK redef
173
+ '''Fast polynomial evaluation M{sum(cs[i] * x**i for i=0..len(cs))}
174
+ but for C{float} C{x} and C{cs} and C{incx=True} only.
175
+ '''
176
+ def __init__(self, x, *cs): # incx=True
177
+ self._ps = []
178
+ for c in reversed(cs): # multiply-accumulate
179
+ self *= x # ps[:] = (x * p for p in ps)
180
+ self += c # self._ps_acc(ps, (c,), up=False)
181
+
141
182
 
142
183
  class GeoidError(HeightError):
143
184
  '''Geoid interpolator C{Geoid...} or interpolation issue.
@@ -484,7 +525,7 @@ class _GeoidBase(_HeightBase):
484
525
 
485
526
  def _load(self, g, dtype=float, n=-1, offset=0, **sep): # sep=NN
486
527
  # numpy.fromfile, like .frombuffer
487
- g.seek(offset, _MODS.os.SEEK_SET)
528
+ g.seek(offset, _os.SEEK_SET)
488
529
  return self.numpy.fromfile(g, dtype, count=n, **sep)
489
530
 
490
531
  @Property_RO
@@ -566,8 +607,8 @@ class _GeoidBase(_HeightBase):
566
607
  def _open(self, geoid, datum, kind, name, smooth):
567
608
  # open the geoid file
568
609
  try:
569
- self._geoid = _MODS.os.path.basename(geoid)
570
- self._sizeB = _MODS.os.path.getsize(geoid)
610
+ self._geoid = _os.path.basename(geoid)
611
+ self._sizeB = _os.path.getsize(geoid)
571
612
  g = open(geoid, _rb_)
572
613
  except (IOError, OSError) as x:
573
614
  raise GeoidError(geoid=geoid, cause=x)
@@ -774,15 +815,11 @@ class GeoidEGM96(_GeoidBase):
774
815
 
775
816
  def _g2ll2(self, lat, lon):
776
817
  # convert grid (lat, lon) to earth (lat, lon)
777
- while lon > _180_0: # Eastern
778
- lon -= _360_0
779
- return -lat, lon # invert lat
818
+ return -lat, _lonE2lon(lon) # invert lat
780
819
 
781
820
  def _ll2g2(self, lat, lon):
782
821
  # convert earth (lat, lon) to grid (lat, lon)
783
- while lon < 0: # Eastern
784
- lon += _360_0
785
- return -lat, lon # invert lat
822
+ return -lat, _lon2lonE(lon) # invert lat
786
823
 
787
824
  if _FOR_DOCS:
788
825
  __call__ = _GeoidBase.__call__
@@ -791,29 +828,27 @@ class GeoidEGM96(_GeoidBase):
791
828
 
792
829
  class GeoidG2012B(_GeoidBase):
793
830
  '''Geoid height interpolator for U{GEOID12B Model
794
- <https://www.NGS.NOAA.gov/GEOID/GEOID12B/>} grids U{CONUS
795
- <https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_CONUS.shtml>},
796
- U{Alaska<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_AK.shtml>},
797
- U{Hawaii<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_HI.shtml>},
831
+ <https://Geodesy.NOAA.gov/GEOID/GEOID12B/>} grids U{CONUS
832
+ <https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_CONUS.shtml>},
833
+ U{Alaska<https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_AK.shtml>},
834
+ U{Hawaii<https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_HI.shtml>},
798
835
  U{Guam and Northern Mariana Islands
799
- <https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_GMNI.shtml>},
836
+ <https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_GMNI.shtml>},
800
837
  U{Puerto Rico and U.S. Virgin Islands
801
- <https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_PRVI.shtml>} and
802
- U{American Samoa<https://www.NGS.NOAA.gov/GEOID/GEOID12B/GEOID12B_AS.shtml>}
838
+ <https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_PRVI.shtml>} and
839
+ U{American Samoa<https://Geodesy.NOAA.gov/GEOID/GEOID12B/GEOID12B_AS.shtml>}
803
840
  based on C{SciPy} interpolation U{RectBivariateSpline<https://docs.SciPy.org/doc/
804
841
  scipy/reference/generated/scipy.interpolate.RectBivariateSpline.html>}, U{interp2d
805
842
  <https://docs.SciPy.org/doc/scipy/reference/generated/scipy.interpolate.interp2d.html>}
806
843
  or U{bisplrep/-ev<https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.
807
844
  bisplrep.html>}.
808
-
809
- Use any of the C{le} (little endian) or C{be} (big endian) C{g2012b*.bin} binary grid files.
810
845
  '''
811
846
  _datum = Datums.NAD83
812
847
 
813
848
  def __init__(self, g2012b_bin, datum=Datums.NAD83, kind=3, smooth=0, **name_crop):
814
849
  '''New L{GeoidG2012B} interpolator.
815
850
 
816
- @arg g2012b_bin: A C{GEOID12B} grid file name (C{.bin}).
851
+ @arg g2012b_bin: A C{GEOID12B} grid file name (C{.bin}, see B{note}).
817
852
  @kwarg datum: Optional grid datum (L{Datum}, L{Ellipsoid}, L{Ellipsoid2} or
818
853
  L{a_f2Tuple}), overriding C{NAD83}.
819
854
  @kwarg kind: C{scipy.interpolate} order (C{int}), use 1..5 for U{RectBivariateSpline
@@ -827,8 +862,8 @@ class GeoidG2012B(_GeoidBase):
827
862
  @kwarg name_crop: Optional geoid C{B{name}=NN} (C{str}) and UNSUPPORTED keyword argument
828
863
  C{B{crop}=None}.
829
864
 
830
- @raise GeoidError: Invalid B{C{crop}}, B{C{kind}} or B{C{smooth}} or a G2012B grid file
831
- B{C{g2012b_bin}} issue.
865
+ @raise GeoidError: Invalid B{C{crop}}, B{C{kind}} or B{C{smooth}} or a B{C{g2012b_bin}}
866
+ grid file issue.
832
867
 
833
868
  @raise ImportError: Package C{numpy} or C{scipy} not found or not installed.
834
869
 
@@ -840,8 +875,11 @@ class GeoidG2012B(_GeoidBase):
840
875
 
841
876
  @raise TypeError: Invalid B{C{datum}}.
842
877
 
843
- @note: Specify C{B{kind}=-1, -3 or -5} to use C{scipy.interpolate.interp2d}
844
- before or C{scipy.interpolate.bisplrep/-ev} since C{Scipy} version 1.14.
878
+ @note: Only use any of the C{le} (little-endian) or C{be} (big-endian) C{g2012b*.bin}
879
+ I{binary} grid files.
880
+
881
+ @note: Specify C{B{kind}=-1, -3 or -5} to use C{scipy.interpolate.interp2d} I{before}
882
+ or C{scipy.interpolate.bisplrep/-ev} I{since} C{Scipy} version 1.14.
845
883
  '''
846
884
  crop, name = _xkwds_pop2(name_crop, crop=None)
847
885
  if crop is not None:
@@ -871,7 +909,7 @@ class GeoidG2012B(_GeoidBase):
871
909
  p.slat, p.wlon, p.dlat, p.dlon = map(float, self._load(g, en_+'f8', 4))
872
910
  # read all f4 heights, ignoring the first 4xf8 and 3xi4
873
911
  hs = self._load(g, self._endian, n, 44).reshape(p.nlat, p.nlon)
874
- p.wlon -= _360_0 # western-most East longitude to earth (..., lon)
912
+ p.wlon -= _360_0 # western-most lon XXX _lonE2lon
875
913
  _GeoidBase.__init__(self, hs, p)
876
914
 
877
915
  except Exception as x:
@@ -975,12 +1013,12 @@ class GeoidKarney(_GeoidBase):
975
1013
  _CM = (_T(' 0, -1'), # 10x12 cubic matrix [i, j] indices
976
1014
  _T(' 1, -1'),
977
1015
  _T('-1, 0'),
978
- _T(' 0, 0'),
979
- _T(' 1, 0'),
1016
+ _T(' 0, 0'), # _BT[0]
1017
+ _T(' 1, 0'), # _BT[1]
980
1018
  _T(' 2, 0'),
981
1019
  _T('-1, 1'),
982
- _T(' 0, 1'),
983
- _T(' 1, 1'),
1020
+ _T(' 0, 1'), # _BT[2]
1021
+ _T(' 1, 1'), # _BT[3]
984
1022
  _T(' 2, 1'),
985
1023
  _T(' 0, 2'),
986
1024
  _T(' 1, 2'))
@@ -1063,7 +1101,7 @@ class GeoidKarney(_GeoidBase):
1063
1101
  p = self._pgm
1064
1102
  if 0 < x < (p.nlon - 2) and 0 < y < (p.nlat - 2):
1065
1103
  # read 4x4 ushorts, drop the 4 corners
1066
- S = _MODS.os.SEEK_SET
1104
+ S = _os.SEEK_SET
1067
1105
  e = self._4endian
1068
1106
  g = self._egm
1069
1107
  n = self._4u2B
@@ -1099,7 +1137,7 @@ class GeoidKarney(_GeoidBase):
1099
1137
  y, x = int(_floor(fy)), int(_floor(fx))
1100
1138
  fy -= y
1101
1139
  fx -= x
1102
- H = self._ev2d(fy, fx, y, x) # PYCHOK ._ev2k or ._ev3k
1140
+ H = self._ev2d(fy, fx, y, x) # PYCHOK ._ev3k or ._ev2k
1103
1141
  H *= self._pgm.Scale # H.fmul(self._pgm.Scale)
1104
1142
  H += self._pgm.Offset # H.fadd(self._pgm.Offset)
1105
1143
  return H.fsum() # float(H)
@@ -1112,10 +1150,10 @@ class GeoidKarney(_GeoidBase):
1112
1150
  y, x = self._yx_i = yx
1113
1151
  self._yx_t = self._raws(y, x, GeoidKarney._BT)
1114
1152
  t = self._yx_t
1115
- v = _1_0, -fx, fx
1116
- H = Fdot(v, t[0], t[0], t[1]).fmul(_1_0 - fy) # c = a * (1 - fy)
1117
- H += Fdot(v, t[2], t[2], t[3]).fmul(fy) # c += b * fy
1118
- return H
1153
+ v = _1_0, (-fx), fx
1154
+ H = _Dotf(v, t[0], t[0], t[1]).fmul(_1_0 - fy) # c = a * (1 - fy)
1155
+ H += _Dotf(v, t[2], t[2], t[3]).fmul(fy) # c += b * fy
1156
+ return H # Fsum
1119
1157
 
1120
1158
  def _ev3k(self, fy, fx, *yx):
1121
1159
  # compute the cubic 10-tuple and interpolate raw H
@@ -1124,7 +1162,7 @@ class GeoidKarney(_GeoidBase):
1124
1162
  else:
1125
1163
  c0, c3, v = self._c0c3v(*yx)
1126
1164
  # assert len(c3) == self._nterms
1127
- self._yx_t = tuple(fdot(v, *r3) / c0 for r3 in c3)
1165
+ self._yx_t = tuple(_Dotf(v, *r3).fover(c0) for r3 in c3)
1128
1166
  self._yx_i = yx
1129
1167
  # GeographicLib/Geoid.cpp Geoid::height(lat, lon) ...
1130
1168
  # real h = t[0] + fx * (t[1] + fx * (t[3] + fx * t[6])) +
@@ -1132,20 +1170,18 @@ class GeoidKarney(_GeoidBase):
1132
1170
  # fy * (t[5] + fx * t[8] + fy * t[9]));
1133
1171
  t = self._yx_t
1134
1172
  v = _1_0, fx, fy
1135
- H = Fdot(v, t[5], t[8], t[9])
1136
- H *= fy
1137
- H += Fhorner(fx, t[2], t[4], t[7])
1138
- H *= fy
1139
- H += Fhorner(fx, t[0], t[1], t[3], t[6])
1140
- return H
1173
+ H = _Dotf(v, t[5], t[8], t[9])
1174
+ H *= fy
1175
+ H += _Hornerf(fx, t[2], t[4], t[7])
1176
+ H *= fy
1177
+ H += _Hornerf(fx, t[0], t[1], t[3], t[6])
1178
+ return H # Fsum
1141
1179
 
1142
1180
  _ev2d = _ev3k # overriden for kind=2, see ._ev_name
1143
1181
 
1144
1182
  def _g2ll2(self, lat, lon):
1145
1183
  # convert grid (lat, lon) to earth (lat, lon), uncropped
1146
- while lon > _180_0:
1147
- lon -= _360_0
1148
- return lat, lon
1184
+ return lat, _lonE2lon(lon)
1149
1185
 
1150
1186
  def _g2yx2(self, lat, lon):
1151
1187
  # convert grid (lat, lon) to grid (y, x) indices
@@ -1188,9 +1224,7 @@ class GeoidKarney(_GeoidBase):
1188
1224
 
1189
1225
  def _ll2g2(self, lat, lon):
1190
1226
  # convert earth (lat, lon) to grid (lat, lon), uncropped
1191
- while lon < 0:
1192
- lon += _360_0
1193
- return lat, lon
1227
+ return lat, _lon2lonE(lon)
1194
1228
 
1195
1229
  def _llh3minmax(self, highest, *lat2):
1196
1230
  # find highest or lowest, takes 10+ secs for egm2008-1.pgm geoid
@@ -1277,7 +1311,7 @@ class GeoidKarney(_GeoidBase):
1277
1311
  p, g = self._pgm, self._egm
1278
1312
  if g:
1279
1313
  b = p.skip + (y * p.nlon + x) * self._u2B
1280
- g.seek(b, _MODS.os.SEEK_SET)
1314
+ g.seek(b, _os.SEEK_SET)
1281
1315
  return b # position
1282
1316
  raise GeoidError('closed file', txt=repr(p.egm)) # IOError
1283
1317
 
@@ -1347,7 +1381,7 @@ class GeoidPGM(_GeoidBase):
1347
1381
  the available memory, especially with 32-bit Python. To reduce memory
1348
1382
  usage, set keyword argument B{C{crop}} to the region of interest. For
1349
1383
  example C{B{crop}=(20, -125, 50, -65)} covers the U{conterminous US
1350
- <https://www.NGS.NOAA.gov/GEOID/GEOID12B/maps/GEOID12B_CONUS_grids.png>}
1384
+ <https://Geodesy.NOAA.gov/GEOID/GEOID12B/maps/GEOID12B_CONUS_grids.png>}
1351
1385
  (CONUS), less than 3% of the entire C{egm2008-1.pgm} dataset.
1352
1386
 
1353
1387
  @see: Class L{GeoidKarney} and function L{egmGeoidHeights}.
@@ -1382,8 +1416,7 @@ class GeoidPGM(_GeoidBase):
1382
1416
  if self._cropped:
1383
1417
  lon -= self._lon_of
1384
1418
  else:
1385
- while lon > _180_0:
1386
- lon -= _360_0
1419
+ lon = _lonE2lon(lon)
1387
1420
  return lat, lon
1388
1421
 
1389
1422
  def _ll2g2(self, lat, lon):
@@ -1391,8 +1424,7 @@ class GeoidPGM(_GeoidBase):
1391
1424
  if self._cropped:
1392
1425
  lon += self._lon_of
1393
1426
  else:
1394
- while lon < 0:
1395
- lon += _360_0
1427
+ lon = _lon2lonE(lon)
1396
1428
  return lat, lon
1397
1429
 
1398
1430
  if _FOR_DOCS:
@@ -1541,8 +1573,8 @@ class _PGM(_Gpars):
1541
1573
  self.slat, self.wlon = self.Origin
1542
1574
  # note, negative .dlat and .rlat since rows
1543
1575
  # are from .slat 90N down in decreasing lat
1544
- self.dlat, self.dlon = _180_0 / (1 - nlat), _360_0 / nlon
1545
- self.rlat, self.rlon = (1 - nlat) / _180_0, nlon / _360_0
1576
+ self.dlat, self.dlon = (_180_0 / (1 - nlat)), (_360_0 / nlon)
1577
+ self.rlat, self.rlon = ((1 - nlat) / _180_0), (nlon / _360_0)
1546
1578
 
1547
1579
  # grid corners in earth (lat, lon), .slat = 90, .dlat < 0
1548
1580
  n = float(self.slat)
@@ -1604,11 +1636,11 @@ class _PGM(_Gpars):
1604
1636
  t, c = 0, self._tmpfile()
1605
1637
  # reading (s - n) rows, forward
1606
1638
  for y in range(n, s): # PYCHOK y unused
1607
- g.seek(z, _MODS.os.SEEK_SET)
1639
+ g.seek(z, _os.SEEK_SET)
1608
1640
  # Python 2 tmpfile.write returns None
1609
1641
  t += c.write(g.read(r)) or r
1610
1642
  if p: # wrap around to start of row
1611
- g.seek(-q, _MODS.os.SEEK_CUR)
1643
+ g.seek(-q, _os.SEEK_CUR)
1612
1644
  # assert(g.tell() == (z - w * self.u2B))
1613
1645
  # Python 2 tmpfile.write returns None
1614
1646
  t += c.write(g.read(p)) or p
@@ -1635,7 +1667,7 @@ class _PGM(_Gpars):
1635
1667
  self.knots = k
1636
1668
  self.skip = 0 # no header lines in c
1637
1669
 
1638
- c.seek(0, _MODS.os.SEEK_SET)
1670
+ c.seek(0, _os.SEEK_SET)
1639
1671
  # c = open(c.name, _rb_) # reopen for numpy 1.8.0-
1640
1672
  return c
1641
1673
 
@@ -1659,11 +1691,11 @@ class _PGM(_Gpars):
1659
1691
  try:
1660
1692
  from tempfile import NamedTemporaryFile as tmpfile
1661
1693
  except ImportError: # Python 2.7.16-
1662
- from _MODS.os import tmpfile
1663
- t = _MODS.os.path.basename(self.pgm)
1664
- t = _MODS.os.path.splitext(t)[0]
1694
+ from _os import tmpfile # PYCHOK from
1695
+ t = _os.path.basename(self.pgm)
1696
+ t = _os.path.splitext(t)[0]
1665
1697
  f = tmpfile(mode='w+b', prefix=t or 'egm')
1666
- f.seek(0, _MODS.os.SEEK_SET) # force overwrite
1698
+ f.seek(0, _os.SEEK_SET) # force overwrite
1667
1699
  return f
1668
1700
 
1669
1701
  @Property_RO
@@ -1703,7 +1735,7 @@ def egmGeoidHeights(GeoidHeights_dat):
1703
1735
  dat = _BytesIO(dat)
1704
1736
 
1705
1737
  try:
1706
- dat.seek(0, _MODS.os.SEEK_SET) # reset
1738
+ dat.seek(0, _os.SEEK_SET) # reset
1707
1739
  except AttributeError as x:
1708
1740
  raise GeoidError(GeoidHeights_dat=type(dat), cause=x)
1709
1741
 
@@ -1711,11 +1743,26 @@ def egmGeoidHeights(GeoidHeights_dat):
1711
1743
  t = t.strip()
1712
1744
  if t and not t.startswith(_bHASH_):
1713
1745
  lat, lon, egm84, egm96, egm2008 = map(float, t.split())
1714
- while lon > _180_0: # EasternLon to earth lon
1715
- lon -= _360_0
1746
+ lon = _lonE2lon(lon) # Eastern to earth lon
1716
1747
  yield GeoidHeight5Tuple(lat, lon, egm84, egm96, egm2008)
1717
1748
 
1718
1749
 
1750
+ def _lonE2lon(lon):
1751
+ '''(INTERNAL) East to earth longitude.
1752
+ '''
1753
+ while lon > _180_0:
1754
+ lon -= _360_0
1755
+ return lon
1756
+
1757
+
1758
+ def _lon2lonE(lon):
1759
+ '''(INTERNAL) Earth to East longitude.
1760
+ '''
1761
+ while lon < 0:
1762
+ lon += _360_0
1763
+ return lon
1764
+
1765
+
1719
1766
  __all__ += _ALL_DOCS(_GeoidBase)
1720
1767
 
1721
1768
  if __name__ == _DMAIN_: # MCCABE 14
pygeodesy/heights.py CHANGED
@@ -59,7 +59,7 @@ C{>>> h1, h2, ... = hinterpolator.height_(lat1, lon1, lat2, lon2, ...)}
59
59
  L{HeightSmoothBiSpline} require package U{scipy<https://SciPy.org>}.
60
60
  Classes L{HeightIDWkarney} and L{HeightIDWdistanceTo} -if used with
61
61
  L{ellipsoidalKarney.LatLon} points- require I{Karney}'s U{geographiclib
62
- <https://PyPI.org/project/geographiclib>} to be installed.
62
+ <https://PyPI.org/project/geographiclib>} package to be installed.
63
63
 
64
64
  @note: Errors from C{scipy} are raised as L{SciPyError}s. Warnings issued
65
65
  by C{scipy} can be thrown as L{SciPyWarning} exceptions, provided
@@ -92,7 +92,7 @@ from pygeodesy.units import _isDegrees, Float_, Int_
92
92
  # from math import radians # from .points
93
93
 
94
94
  __all__ = _ALL_LAZY.heights
95
- __version__ = '25.09.29'
95
+ __version__ = '26.02.02'
96
96
 
97
97
  _error_ = 'error'
98
98
  _formy = _MODS.into(formy=__name__)
@@ -160,7 +160,7 @@ def _orderedup(ts, lo=EPS, hi=PI2-EPS):
160
160
  return sorted(set(max(lo, min(hi, t)) for t in ts)) # list
161
161
 
162
162
 
163
- def _xyhs(wrap=False, _lat=_90_0, _lon=_180_0, **name_lls):
163
+ def _xyhs(wrap=False, _lat=_90_0, _lon=_180_0, height=True, **name_lls):
164
164
  # map (lat, lon, h) to (x, y, h) in radians, offset
165
165
  # x as 0 <= lon <= PI2 and y as 0 <= lat <= PI
166
166
  name, lls = _xkwds_item2(name_lls)
@@ -168,8 +168,9 @@ def _xyhs(wrap=False, _lat=_90_0, _lon=_180_0, **name_lls):
168
168
  try:
169
169
  for i, ll in enumerate(lls):
170
170
  y, x = _w(ll.lat, ll.lon)
171
- yield max(_0_0, _r(x + _lon)), \
172
- max(_0_0, _r(y + _lat)), ll.height
171
+ h = ll.height if height else 0
172
+ yield (max(_0_0, _r(x + _lon)),
173
+ max(_0_0, _r(y + _lat)), h)
173
174
  except Exception as x:
174
175
  i = Fmt.INDEX(name, i)
175
176
  raise HeightError(i, ll, cause=x)
@@ -266,9 +267,9 @@ class _HeightBase(_HeightNamed): # in .geoids
266
267
  # convert lli C{LatLon}s to tuples or C{NumPy} arrays of
267
268
  # C{SciPy} sphericals and determine the return type
268
269
  atype = self.numpy.array
269
- wrap = _xkwds(wrap, wrap=self._wrap)
270
+ kwds = _xkwds(wrap, wrap=self._wrap, height=False)
270
271
  _as, llis = _as_llis2(llis)
271
- xis, yis, _ = zip(*_xyhs(llis=llis, **wrap)) # PYCHOK yield
272
+ xis, yis, _ = zip(*_xyhs(llis=llis, **kwds)) # PYCHOK yield
272
273
  return _as, atype(xis), atype(yis), llis
273
274
 
274
275
  def _ev(self, *args): # PYCHOK no cover
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pygeodesy
3
- Version: 26.1.16
3
+ Version: 26.2.2
4
4
  Summary: Pure Python geodesy tools
5
5
  Home-page: https://GitHub.com/mrJean1/PyGeodesy
6
6
  Author: Jean M. Brouwers
@@ -8,7 +8,7 @@ Author-email: mrJean1@Gmail.com
8
8
  Maintainer: Jean M. Brouwers
9
9
  Maintainer-email: mrJean1@Gmail.com
10
10
  License: MIT
11
- Keywords: AER AGM Albers altitude Andoyer annulus antipode area Arithmetic-Geometric-Mean attitude Authalic auxiliary azimuth azimuthal azimuth-elevation-range bearing bank Barsky Barth beta bi-quadratic boolean cached Cagnoli cartesian Cassini Cassini-Soldner chord circle-intersections circumcenter circumcircle circumradius clip Cohen Cohen-Sutherland Collins composite conformal conformal-sphere conic constants contact-triangle Cook Correia cosines-law coverage curvature cylindrical datum deprecation deficit development discrete distance Douglas earth east-north-up eccentricity ECEF elevation ellipsoid ellipsoidal-latitude-beta ellipsoidal-longitude-omega elliptic ENU EPSG equal-area equidistant equirectangular ETM ETRF Euclidean even-odd-rule ExactTM excess Farrell Farrell-Barth Ferrari-solution Field-Of-View flattening fma fmath footpoint footprint Forster Forster-Hormann-Popa Forsythe FOV fractional Frechet Fréchet frustum Fsum fused-multiply-add GARS Gauss-Kummer geocentric GeoConvert GeodesicExact geodesy geodetic GeodSolve Geod3Solve GeodTest geographiclib Geohash geoid geoidHeight GeoidHeights georef Girard gnomonic gons grades gradians Greiner Greiner-Hormann Hartzell Hausdorff Haversine heading hectare height Heikkinen Heron Hodgman horizon Hormann Hubeny IDW incenter incirle infix_@_operator inradius intermediate interpolate intersect intersection intersection3d intersections IntersectTool Inverse-Distance-Weighting Isometric ITRF Jacobi Jacobi-Conformal Jarque-Bera Jekel Karney Krueger Krüger kurtosis Lambert latitude law-of-cosines least-squares Lesh L_Huilier LHuilier Liang Liang-Barsky Linderholm-Segal linearize Line-Of-Sight LocalCartesian local-tangent-plane local-x-y-z longitude LOS loxodrome lstsq LTP lune LV03 LV95 mean memoize memoized Mercator Meeus MGRS nearest NED Niemeyer non-finite normalize Norrdine north-east-down numpy n-vector Nvector oblate omega orthographic orthometric-height OSGB OSGR overlap parallel parallel-of-latitude Parametric path-intersection perimeter Peucker Pierlot pitch plumb Point-Of-View polar Popa POV precision-cubic-root precision-hypotenuse precision-powers precision-running-summation precision-square-root precision-summation prolate Pseudo-Mercator pygeodesy PyInstaller PyPy quartic radical radii radius Ramanujan Ramer Ramer-Douglas-Peucker Rectifying Reduced resect resection Rey-Jer Reumann Reumann-Witkam rho-theta-phi rhumb RhumbSolve running-linear-regression running-statistics running-stats running-summation scipy secant semi-perimeter sexagecimal simplify skewness Snellius Snellius-Pothenot Snyder Soddy Soddy-circles Soldner sphere sphere-intersections spherical-deficit spherical-excess spherical-polar spherical-triangle squared-quartic standard-deviation stereographic Sudano surface-area Sutherland Sutherland-Hodgman tangent-circles Terrestrial-Reference-Frame Thomas Tienstra tilt TMcoords TMExact toise transverse TransverseMercatorExact TRF triangle triangulate triaxial triaxial-ellipsoid trigonometry trilaterate trilaterate-2d trilaterate-3d TwoProduct TwoSum umbilic-point unit unroll UPS UTM UTM/UPS variance velocities Veness Vermeille viewing-frustum Vincenty Visvalingam Visvalingam-Whyatt volume volumetric Web-Mercator Welford WGRS WGS Whyatt Wildberger Witkam winding-number XYZ yaw You zenzi-cubic zenzi-quartic
11
+ Keywords: AER AGM Albers altitude Andoyer annulus antipode area Arithmetic-Geometric-Mean attitude Authalic auxiliary azimuth azimuthal azimuth-elevation-range bearing bank Barsky Barth beta bi-quadratic boolean cached Cagnoli cartesian Cassini Cassini-Soldner chord circle-intersections circumcenter circumcircle circumradius clip Cohen Cohen-Sutherland Collins composite conformal conformal-sphere conic constants contact-triangle Cook Correia cosines-law coverage curvature cylindrical datum deprecation deficit development discrete distance Douglas earth east-north-up eccentricity ECEF elevation ellipse ellipsoid ellipsoidal-latitude-beta ellipsoidal-longitude-omega elliptic ENU EPSG equal-area equidistant equirectangular ETM ETRF Euclidean even-odd-rule ExactTM excess Farrell Farrell-Barth Ferrari-solution Field-Of-View flattening fma fmath footpoint footprint Forster Forster-Hormann-Popa Forsythe FOV fractional Frechet Fréchet frustum Fsum fused-multiply-add GARS Gauss-Kummer geocentric GeoConvert GeodesicExact geodesy geodetic GeodSolve Geod3Solve GeodTest geographiclib Geohash geoid geoidHeight GeoidHeights georef Girard gnomonic gons grades gradians Greiner Greiner-Hormann Hartzell Hausdorff Haversine heading hectare height Heikkinen Heron Hodgman horizon Hormann Hubeny IDW incenter incirle infix_@_operator inradius intermediate interpolate intersect intersection intersection3d intersections IntersectTool Inverse-Distance-Weighting Isometric ITRF Jacobi Jacobi-Conformal Jarque-Bera Jekel Karney Krueger Krüger kurtosis Lambert latitude law-of-cosines least-squares Lesh L_Huilier LHuilier Liang Liang-Barsky Linderholm-Segal linearize Line-Of-Sight LocalCartesian local-tangent-plane local-x-y-z longitude LOS loxodrome lstsq LTP lune LV03 LV95 mean memoize memoized Mercator Meeus MGRS nearest NED Niemeyer non-finite normalize Norrdine north-east-down numpy n-vector Nvector oblate omega orthographic orthometric-height OSGB OSGR overlap parallel parallel-of-latitude Parametric path-intersection perimeter Peucker Pierlot pitch plumb Point-Of-View polar Popa POV precision-cubic-root precision-hypotenuse precision-powers precision-running-summation precision-square-root precision-summation prolate Pseudo-Mercator pygeodesy PyInstaller PyPy quartic radical radii radius Ramanujan Ramer Ramer-Douglas-Peucker Rectifying Reduced resect resection Rey-Jer Reumann Reumann-Witkam rho-theta-phi rhumb RhumbSolve running-linear-regression running-statistics running-stats running-summation scipy secant semi-perimeter sexagecimal simplify skewness Snellius Snellius-Pothenot Snyder Soddy Soddy-circles Soldner sphere sphere-intersections spherical-deficit spherical-excess spherical-polar spherical-triangle squared-quartic standard-deviation stereographic Sudano surface-area Sutherland Sutherland-Hodgman tangent-circles Terrestrial-Reference-Frame Thomas Tienstra tilt TMcoords TMExact toise transverse TransverseMercatorExact TRF triangle triangulate triaxial triaxial-ellipsoid trigonometry trilaterate trilaterate-2d trilaterate-3d TwoProduct TwoSum umbilic-point unit unroll UPS UTM UTM/UPS variance velocities Veness Vermeille viewing-frustum Vincenty Visvalingam Visvalingam-Whyatt volume volumetric Web-Mercator Welford WGRS WGS Whyatt Wildberger Witkam winding-number XYZ yaw You zenzi-cubic zenzi-quartic
12
12
  Classifier: Development Status :: 5 - Production/Stable
13
13
  Classifier: Environment :: Console
14
14
  Classifier: Intended Audience :: Developers
@@ -171,7 +171,7 @@ PyCodeStyle_ (formerly Pep8) and McCabe_ using Python 2.7.18, both in 64-bit on
171
171
 
172
172
  For a summary of all *Karney*-based functionality in ``pygeodesy``, see module karney_.
173
173
 
174
- *Last updated: Jan 16, 2026.*
174
+ *Last updated: Feb 02, 2026.*
175
175
 
176
176
  License
177
177
  =======
@@ -1,5 +1,5 @@
1
1
  pygeodesy/LICENSE,sha256=YfgAiyxOwY6P9Kkb1_5XN81nueTLrpb3Ffkv3EuPgFU,1144
2
- pygeodesy/__init__.py,sha256=DmJmEyYy4jSMO4rkA65hK5ZTWBan1UwlXKGAehPbWoc,43790
2
+ pygeodesy/__init__.py,sha256=22CZUTpgF_0-L5ZLo-wpXgBAtgi8sQFXTN6E8P_Csbw,43790
3
3
  pygeodesy/__main__.py,sha256=06sdpwiuTP1hPvKOdzjqhuuDqqpicErwnAYwioeiTNw,5597
4
4
  pygeodesy/albers.py,sha256=6S0hHJA6MspeKLsQHW0cFUpJcWRL1yGshJxtEgJ9PMQ,30908
5
5
  pygeodesy/angles.py,sha256=68sNVXU3QKGZnIYyjWFcKhWlBKSmaduO--rjtoM2sqU,29996
@@ -23,7 +23,7 @@ pygeodesy/ellipsoidalKarney.py,sha256=CxPB91CKA0q5E97TOcErTTQdufdB2dT4KF84QZtfnG
23
23
  pygeodesy/ellipsoidalNvector.py,sha256=48N-KtVUn0wi9kXZe12hg0jABWNeaiNXyY__oS-x5I4,30146
24
24
  pygeodesy/ellipsoidalVincenty.py,sha256=X4OpMPtoretveNjHlEXKL4ifmAARTRY0yxbIOlR26J8,26273
25
25
  pygeodesy/ellipsoids.py,sha256=5UwnIOpDCFrxqQIF9mkQUEEPW2H1YRog_MpYkvcYx7c,109248
26
- pygeodesy/elliptic.py,sha256=xCllssJSm2O4W2Mo2hb1f65pT-GcaVwQuIpzR84eD7Y,59483
26
+ pygeodesy/elliptic.py,sha256=nUBHDM9v-dQt9WHHKSBRB74Hd5zysG1TyKom8nlSN-o,59505
27
27
  pygeodesy/epsg.py,sha256=wS8Mzzk70Fzry6c0fBA16VVez3ghKG2Dhgpo2eN_Ik8,8220
28
28
  pygeodesy/errors.py,sha256=76wVrhxev-n-kBOHv3MicHell3ifA2whUp4SRCrqUx4,32633
29
29
  pygeodesy/etm.py,sha256=3pQmpjsrnI0mgLwhkLOCOFq_44bkhHwXExf-Keyky2w,46796
@@ -31,16 +31,16 @@ pygeodesy/fmath.py,sha256=OUitWAuSM7OzlbJJ_JahfUjsVrIv5Bnt4U_0pUgXTQ4,37995
31
31
  pygeodesy/formy.py,sha256=TSDEyzOInkhmeZYVRjoOl4oO7wCFrE2YLWGTs9Ewa_4,69842
32
32
  pygeodesy/frechet.py,sha256=FySLdZgLb_NXd81AILx4G2C9J6dxwI5uYW1MEHuEocg,35588
33
33
  pygeodesy/fstats.py,sha256=EuyC9UrJ5K0IlZqM7h3C8C7tYDrTujqoBp9-V1ICPx0,28348
34
- pygeodesy/fsums.py,sha256=VmxnlFld-3z-_xuksKsQinWmzZyeo6CEMM9c9ZabMCU,105500
34
+ pygeodesy/fsums.py,sha256=dh9tXnSE1BNH7oEwq4Zt2G6BGNy5Bz9wJLCde6hYvW0,105954
35
35
  pygeodesy/gars.py,sha256=z7yvE6dRAjtXUAB9yakH8duwF2gBKbcjXUIznNnr8_w,11761
36
36
  pygeodesy/geod3solve.py,sha256=ATQmfkg2KU1YwAgQU32t78Fq5mLvpYykLpqH6TH6mXw,22052
37
37
  pygeodesy/geodesici.py,sha256=eHkXKDQzeFfJ6lVkGANqnEk5hQR-MkYXQlgXCLzbG3Y,74933
38
38
  pygeodesy/geodesicw.py,sha256=bhwSBtHAaNAl487uAgifS42cKvcYTe-8O8M5S44u9_k,30029
39
39
  pygeodesy/geodsolve.py,sha256=GqMn4PjXAT7jK0VjxeMv7FgNx-_T_LeAfeMda7wUSqM,25032
40
40
  pygeodesy/geohash.py,sha256=LmjvzgrzD0Cj-xPCZNJp3LbVOQ7llaE2sAO0V0SxNOo,40124
41
- pygeodesy/geoids.py,sha256=Fn3pOCokzQJuEY2UE11Ah5XuiT24WRmmoc3FeNhfpsg,86129
41
+ pygeodesy/geoids.py,sha256=7r6iEefNKNW6LwacSAnaluiBw3QTl32UbtUEME-kEgU,87606
42
42
  pygeodesy/hausdorff.py,sha256=_zfkZ4pzUE_6LwFD77RU9NC58aN8imglI7TfapM82Wc,32269
43
- pygeodesy/heights.py,sha256=T_5ZhtFAskQf-1BHL2Nm5bTYQIMJj-d1UKhW11YPWvs,41011
43
+ pygeodesy/heights.py,sha256=S7l_Nq4fcfSRJEoFb3_sGK1Gm35AlN6zEjK-Xqafrfk,41082
44
44
  pygeodesy/internals.py,sha256=WPrXmN1GMnVB3JYJbXpC1cZlIYMyU9v1I1rDeHI8yGQ,24934
45
45
  pygeodesy/interns.py,sha256=h7LupB9eEhwgW8mq3R4VMFI3i-49ObgXAEvV2JJmmpM,23521
46
46
  pygeodesy/iters.py,sha256=xH719oFB-0z4jCAHeC6uLqyfWPtpQoSBF6Pgnoz5weQ,20345
@@ -85,9 +85,9 @@ pygeodesy/auxilats/_CX_Rs.py,sha256=EV6Py2yxqtf3FAykmdAHa3Rj9V_yfP21BYwayXNk_zU,
85
85
  pygeodesy/auxilats/__init__.py,sha256=u3hwLEvkaiD4KU-kfHfi26IbKWZHWLIBVukCFYNpQjo,2883
86
86
  pygeodesy/auxilats/__main__.py,sha256=JPDbuG6UnghFtWBbNzb7Uuv9bXDW55ZXXd2PV-6Tc9o,3340
87
87
  pygeodesy/auxilats/auxAngle.py,sha256=QrkiKKHpH7gYoLA5WSdePX0198oDB0yiwGSx0erWLMc,16671
88
- pygeodesy/auxilats/auxDLat.py,sha256=6bamjB_s0RbINNU3V8W9lzsjXl3tWcjkkwLLgusclVM,10956
88
+ pygeodesy/auxilats/auxDLat.py,sha256=djSAVT5CF2D49F6MhCM9utZcYHoXYu4in0iGXDSAeI8,10925
89
89
  pygeodesy/auxilats/auxDST.py,sha256=4VkQ6RfpUA0NvTZawP-bMatJMbrFz3lbzyXKwfQmdB4,10464
90
- pygeodesy/auxilats/auxLat.py,sha256=qWvIdfpvIQUF7jsgJyxeNgkbjlbIPsNs8-uvPMxyJbM,31972
90
+ pygeodesy/auxilats/auxLat.py,sha256=-q5Ks4e5hzn5ZYp1ThiVTm3Qq-E9uvz-o8izNivhp_c,31938
91
91
  pygeodesy/auxilats/auxily.py,sha256=_D-7n-73pVdZR459NF0WGmO3eOVEtiyaongKCGPvHkA,8085
92
92
  pygeodesy/deprecated/__init__.py,sha256=TsSpb0A6l5BelXOuhHvljy6m-UoR0Sf86CsCXlgfuls,2823
93
93
  pygeodesy/deprecated/bases.py,sha256=5cwF5nZ6SmAwib3iEmOJ66yzLfimfl1Ru93U_ohbtkA,1649
@@ -119,7 +119,7 @@ pygeodesy/triaxials/bases.py,sha256=WfF3Up7JFAWrLnvsRpWsncXICjxqbjVZZUbB6EvGFHU,
119
119
  pygeodesy/triaxials/conformal3.py,sha256=FrJLQ0m58YvP_heh9jFH5TkhR46kSTzCIgtmtRPMErQ,23883
120
120
  pygeodesy/triaxials/triaxial3.py,sha256=mTG8Atw7VbGyXWPoD78M-6XM6rarXCwKlatqWl41Hoo,42865
121
121
  pygeodesy/triaxials/triaxial5.py,sha256=nJhVDbNfXSbldL7QCrGAXNsFlIWY-rUAaVLMPcX7x-g,50977
122
- pygeodesy-26.1.16.dist-info/METADATA,sha256=U4um_8MNCzFuw0CYVx46wj3uI-aK9MCcIjYbykv5M1s,20716
123
- pygeodesy-26.1.16.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
124
- pygeodesy-26.1.16.dist-info/top_level.txt,sha256=cEQPatCXzKZqrivpULC5V5fuy9_V_bAwaP_gUGid7pQ,10
125
- pygeodesy-26.1.16.dist-info/RECORD,,
122
+ pygeodesy-26.2.2.dist-info/METADATA,sha256=hBT8G-DrD-R9WaU18rjEVX7wnMaLl4ZNb78BG6zYBdg,20723
123
+ pygeodesy-26.2.2.dist-info/WHEEL,sha256=Kh9pAotZVRFj97E15yTA4iADqXdQfIVTHcNaZTjxeGM,110
124
+ pygeodesy-26.2.2.dist-info/top_level.txt,sha256=cEQPatCXzKZqrivpULC5V5fuy9_V_bAwaP_gUGid7pQ,10
125
+ pygeodesy-26.2.2.dist-info/RECORD,,