[Git][debian-gis-team/pymap3d][upstream] New upstream version 2.7.0

Antonio Valentino (@antonio.valentino) gitlab at salsa.debian.org
Tue Aug 17 11:00:48 BST 2021



Antonio Valentino pushed to branch upstream at Debian GIS Project / pymap3d


Commits:
2e278877 by Antonio Valentino at 2021-08-17T09:40:17+00:00
New upstream version 2.7.0
- - - - -


24 changed files:

- − Examples/vdist.py
- Examples/vdist_stability.py
- − Examples/vreckon.py
- README.md
- pyproject.toml
- setup.cfg
- src/pymap3d/__init__.py
- src/pymap3d/ecef.py
- src/pymap3d/enu.py
- src/pymap3d/latitude.py
- src/pymap3d/lox.py
- src/pymap3d/rcurve.py
- src/pymap3d/rsphere.py
- src/pymap3d/tests/test_geodetic.py
- src/pymap3d/tests/test_latitude.py
- src/pymap3d/tests/test_look_spheroid.py
- src/pymap3d/tests/test_rcurve.py
- src/pymap3d/tests/test_rhumb.py
- src/pymap3d/tests/test_rsphere.py
- src/pymap3d/utils.py
- + src/pymap3d/vdist/__init__.py
- + src/pymap3d/vdist/__main__.py
- + src/pymap3d/vreckon/__init__.py
- + src/pymap3d/vreckon/__main__.py


Changes:

=====================================
Examples/vdist.py deleted
=====================================
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-from pymap3d.vincenty import vdist
-from argparse import ArgumentParser
-
-
-def main():
-    p = ArgumentParser(description="vdist distance between WGS-84 coordinates")
-    p.add_argument("lat1", help="latitude1 WGS-84 [degrees]", type=float)
-    p.add_argument("lon1", help="longitude1 WGS-84 [degrees]", type=float)
-    p.add_argument("lat2", help="latitude2 WGS-84 [degrees]", type=float)
-    p.add_argument("lon2", help="longitude2 WGS-84 [degrees]", type=float)
-    P = p.parse_args()
-
-    dist_m = vdist(P.lat1, P.lon1, P.lat2, P.lon2)
-
-    print("{:.3f} meters {:.3f} deg azimuth".format(*dist_m))
-
-
-if __name__ == "__main__":  # pragma: no cover
-    main()


=====================================
Examples/vdist_stability.py
=====================================
@@ -16,7 +16,7 @@ except ImportError as exc:
 
 
 def matlab_func(lat1: float, lon1: float, lat2: float, lon2: float) -> typing.Tuple[float, float]:
-    """ Using Matlab Engine to do same thing as Pymap3d """
+    """Using Matlab Engine to do same thing as Pymap3d"""
     ell = eng.wgs84Ellipsoid()
     return eng.distance(lat1, lon1, lat2, lon2, ell, nargout=2)
 


=====================================
Examples/vreckon.py deleted
=====================================
@@ -1,22 +0,0 @@
-#!/usr/bin/env python
-from pymap3d.vincenty import vreckon
-from argparse import ArgumentParser
-
-
-def main():
-    p = ArgumentParser(
-        description="Given starting latitude, longitude: find final lat,lon for distance and azimuth"
-    )
-    p.add_argument("lat", help="latitude WGS-84 [degrees]", type=float)
-    p.add_argument("lon", help="longitude WGS-84 [degrees]", type=float)
-    p.add_argument("range", help="range from start point [meters]", type=float)
-    p.add_argument("azimuth", help="clockwise from north: azimuth to start [degrees]", type=float)
-    P = p.parse_args()
-
-    lat2, lon2 = vreckon(P.lat, P.lon, P.range, P.azimuth)
-
-    print("lat, lon = ({:.4f}, {:.4f})".format(lat2, lon2))
-
-
-if __name__ == "__main__":  # pragma: no cover
-    main()


=====================================
README.md
=====================================
@@ -112,6 +112,15 @@ Abbreviations:
 * [NED: North East Down](https://en.wikipedia.org/wiki/North_east_down)
 * [radec: right ascension, declination](https://en.wikipedia.org/wiki/Right_ascension)
 
+### command line
+
+Command line convenience functions provided include:
+
+```sh
+python -m pymap3d.vdist
+python -m pymap3d.vreckon
+```
+
 ### array vs scalar
 
 Use of pymap3d on embedded systems or other streaming data applications often deal with scalar position data.


=====================================
pyproject.toml
=====================================
@@ -1,6 +1,6 @@
 [project]
 name = "pymap3d"
-version = "2.5.1"
+version = "2.6.1"
 description = "pure Python (no prereqs) coordinate conversions, following convention of several popular Matlab routines."
 readme = "README.md"
 requires-python = ">=3.7"


=====================================
setup.cfg
=====================================
@@ -1,6 +1,6 @@
 [metadata]
 name = pymap3d
-version = 2.6.0
+version = 2.7.0
 author = Michael Hirsch, Ph.D.
 author_email = scivision at users.noreply.github.com
 description = pure Python (no prereqs) coordinate conversions, following convention of several popular Matlab routines.


=====================================
src/pymap3d/__init__.py
=====================================
@@ -30,7 +30,7 @@ Companion packages exist for:
 """
 
 from .aer import ecef2aer, aer2ecef, geodetic2aer, aer2geodetic
-from .ellipsoid import Ellipsoid
+
 from .enu import enu2geodetic, geodetic2enu, aer2enu, enu2aer
 from .ned import ned2ecef, ned2geodetic, geodetic2ned, ecef2nedv, ned2aer, aer2ned, ecef2ned
 from .ecef import (
@@ -45,34 +45,7 @@ from .ecef import (
     uvw2enu,
 )
 from .sidereal import datetime2sidereal, greenwichsrt
-from .latitude import (
-    geod2geoc,
-    geoc2geod,
-    geodetic2geocentric,
-    geocentric2geodetic,
-    geodetic2isometric,
-    isometric2geodetic,
-    geodetic2conformal,
-    conformal2geodetic,
-    geodetic2rectifying,
-    rectifying2geodetic,
-    geodetic2authalic,
-    authalic2geodetic,
-    geodetic2parametric,
-    parametric2geodetic,
-)
-from .rcurve import geocentric_radius, rcurve_parallel, rcurve_meridian, rcurve_transverse
-from .rsphere import (
-    rsphere_eqavol,
-    rsphere_authalic,
-    rsphere_rectifying,
-    rsphere_euler,
-    rsphere_curve,
-    rsphere_triaxial,
-    rsphere_biaxial,
-)
-from .lox import meridian_arc, meridian_dist, loxodrome_inverse, loxodrome_direct, departure, meanm
-from .los import lookAtSpheroid
+from .ellipsoid import Ellipsoid
 from .timeconv import str2dt
 
 try:


=====================================
src/pymap3d/ecef.py
=====================================
@@ -187,7 +187,7 @@ def ecef2geodetic(
     try:
         if inside.any():  # type: ignore
             # avoid all false assignment bug
-            alt[inside] = -alt
+            alt[inside] = -alt[inside]
     except (TypeError, AttributeError):
         if inside:
             alt = -alt


=====================================
src/pymap3d/enu.py
=====================================
@@ -2,19 +2,18 @@
 from __future__ import annotations
 import typing
 
+from math import tau
+
 try:
-    from numpy import asarray, radians, sin, cos, hypot, arctan2 as atan2, degrees, pi, ndarray
+    from numpy import asarray, radians, sin, cos, hypot, arctan2 as atan2, degrees, ndarray
 except ImportError:
-    from math import radians, sin, cos, hypot, atan2, degrees, pi  # type: ignore
+    from math import radians, sin, cos, hypot, atan2, degrees  # type: ignore
 
     ndarray = typing.Any  # type: ignore
 
 from .ecef import geodetic2ecef, ecef2geodetic, enu2ecef, uvw2enu
 from .ellipsoid import Ellipsoid
 
-# py < 3.6 compatible
-tau = 2 * pi
-
 __all__ = ["enu2aer", "aer2enu", "enu2geodetic", "geodetic2enu"]
 
 


=====================================
src/pymap3d/latitude.py
=====================================
@@ -2,9 +2,10 @@
 
 from __future__ import annotations
 import typing
+
 from .ellipsoid import Ellipsoid
 from .utils import sanitize
-from .rcurve import rcurve_transverse
+from . import rcurve
 
 try:
     from numpy import radians, degrees, tan, sin, exp, pi, sqrt, inf, ndarray
@@ -115,7 +116,7 @@ def geodetic2geocentric(
     Office, Washington, DC, 1987, pp. 13-18.
     """
     geodetic_lat, ell = sanitize(geodetic_lat, ell, deg)
-    r = rcurve_transverse(geodetic_lat, ell, deg=False)
+    r = rcurve.transverse(geodetic_lat, ell, deg=False)
     geocentric_lat = atan((1 - ell.eccentricity ** 2 * (r / (r + alt_m))) * tan(geodetic_lat))
 
     return degrees(geocentric_lat) if deg else geocentric_lat
@@ -156,7 +157,7 @@ def geocentric2geodetic(
     Office, Washington, DC, 1987, pp. 13-18.
     """
     geocentric_lat, ell = sanitize(geocentric_lat, ell, deg)
-    r = rcurve_transverse(geocentric_lat, ell, deg=False)
+    r = rcurve.transverse(geocentric_lat, ell, deg=False)
     geodetic_lat = atan(tan(geocentric_lat) / (1 - ell.eccentricity ** 2 * (r / (r + alt_m))))
 
     return degrees(geodetic_lat) if deg else geodetic_lat


=====================================
src/pymap3d/lox.py
=====================================
@@ -12,8 +12,8 @@ except ImportError:
 
 import typing
 from .ellipsoid import Ellipsoid
-from .rcurve import rcurve_parallel
-from .rsphere import rsphere_rectifying
+from . import rcurve
+from . import rsphere
 from .latitude import (
     geodetic2rectifying,
     rectifying2geodetic,
@@ -79,7 +79,7 @@ def meridian_arc(lat1, lat2: ndarray, ell: Ellipsoid = None, deg: bool = True) -
     rlat1 = geodetic2rectifying(lat1, ell, deg=False)
     rlat2 = geodetic2rectifying(lat2, ell, deg=False)
 
-    return rsphere_rectifying(ell) * abs(rlat2 - rlat1)
+    return rsphere.rectifying(ell) * abs(rlat2 - rlat1)
 
 
 def loxodrome_inverse(
@@ -220,7 +220,7 @@ def loxodrome_direct(
 
     # compute the new points
     cosaz = cos(a12)
-    lat2 = reclat + (rng / rsphere_rectifying(ell)) * cosaz  # compute rectifying latitude
+    lat2 = reclat + (rng / rsphere.rectifying(ell)) * cosaz  # compute rectifying latitude
     lat2 = rectifying2geodetic(lat2, ell, deg=False)  # transform to geodetic latitude
 
     newiso = geodetic2isometric(lat2, ell, deg=False)
@@ -265,7 +265,7 @@ def departure(
     if deg:
         lon1, lon2, lat = radians(lon1), radians(lon2), radians(lat)
 
-    return rcurve_parallel(lat, ell, deg=False) * ((lon2 - lon1) % pi)
+    return rcurve.parallel(lat, ell, deg=False) * ((lon2 - lon1) % pi)
 
 
 def meanm(


=====================================
src/pymap3d/rcurve.py
=====================================
@@ -13,7 +13,7 @@ except ImportError:
 from .ellipsoid import Ellipsoid
 from .utils import sanitize
 
-__all__ = ["rcurve_parallel", "rcurve_meridian", "rcurve_transverse", "geocentric_radius"]
+__all__ = ["parallel", "meridian", "transverse", "geocentric_radius"]
 
 
 def geocentric_radius(geodetic_lat: float, ell: Ellipsoid = None, deg: bool = True) -> float:
@@ -36,7 +36,7 @@ def geocentric_radius(geodetic_lat: float, ell: Ellipsoid = None, deg: bool = Tr
     )
 
 
-def rcurve_parallel(lat: ndarray, ell: Ellipsoid = None, deg: bool = True) -> float:
+def parallel(lat: ndarray, ell: Ellipsoid = None, deg: bool = True) -> float:
     """
     computes the radius of the small circle encompassing the globe at the specified latitude
 
@@ -58,10 +58,10 @@ def rcurve_parallel(lat: ndarray, ell: Ellipsoid = None, deg: bool = True) -> fl
     if deg:
         lat = radians(lat)
 
-    return cos(lat) * rcurve_transverse(lat, ell, deg=False)
+    return cos(lat) * transverse(lat, ell, deg=False)
 
 
-def rcurve_meridian(lat: float, ell: Ellipsoid = None, deg: bool = True) -> float:
+def meridian(lat: float, ell: Ellipsoid = None, deg: bool = True) -> float:
     """computes the meridional radius of curvature for the ellipsoid
 
     like Matlab rcurve('meridian', ...)
@@ -91,7 +91,7 @@ def rcurve_meridian(lat: float, ell: Ellipsoid = None, deg: bool = True) -> floa
     return f1 / sqrt(f2 ** 3)
 
 
-def rcurve_transverse(lat: float | ndarray, ell: Ellipsoid = None, deg: bool = True) -> float:
+def transverse(lat: float | ndarray, ell: Ellipsoid = None, deg: bool = True) -> float:
     """computes the radius of the curve formed by a plane
     intersecting the ellipsoid at the latitude which is
     normal to the surface of the ellipsoid


=====================================
src/pymap3d/rsphere.py
=====================================
@@ -12,22 +12,22 @@ except ImportError:
     ndarray = typing.Any  # type: ignore
 
 from .ellipsoid import Ellipsoid
-from .rcurve import rcurve_meridian, rcurve_transverse
+from . import rcurve
 from .vincenty import vdist
 
 
 __all__ = [
-    "rsphere_eqavol",
-    "rsphere_authalic",
-    "rsphere_rectifying",
-    "rsphere_euler",
-    "rsphere_curve",
-    "rsphere_triaxial",
-    "rsphere_biaxial",
+    "eqavol",
+    "authalic",
+    "rectifying",
+    "euler",
+    "curve",
+    "triaxial",
+    "biaxial",
 ]
 
 
-def rsphere_eqavol(ell: Ellipsoid = None) -> float:
+def eqavol(ell: Ellipsoid = None) -> float:
     """computes the radius of the sphere with equal volume as the ellipsoid
 
     Parameters
@@ -48,7 +48,7 @@ def rsphere_eqavol(ell: Ellipsoid = None) -> float:
     return ell.semimajor_axis * (1 - f / 3 - f ** 2 / 9)
 
 
-def rsphere_authalic(ell: Ellipsoid = None) -> float:
+def authalic(ell: Ellipsoid = None) -> float:
     """computes the radius of the sphere with equal surface area as the ellipsoid
 
     Parameters
@@ -75,7 +75,7 @@ def rsphere_authalic(ell: Ellipsoid = None) -> float:
         return ell.semimajor_axis
 
 
-def rsphere_rectifying(ell: Ellipsoid = None) -> float:
+def rectifying(ell: Ellipsoid = None) -> float:
     """computes the radius of the sphere with equal meridional distances as the ellipsoid
 
     Parameters
@@ -93,7 +93,7 @@ def rsphere_rectifying(ell: Ellipsoid = None) -> float:
     return ((ell.semimajor_axis ** (3 / 2) + ell.semiminor_axis ** (3 / 2)) / 2) ** (2 / 3)
 
 
-def rsphere_euler(
+def euler(
     lat1: ndarray,
     lon1: ndarray,
     lat2: ndarray,
@@ -131,8 +131,8 @@ def rsphere_euler(
     az = vdist(lat1, lon1, lat2, lon2, ell=ell)[1]
 
     #   compute meridional and transverse radii of curvature
-    rho = rcurve_meridian(latmid, ell, deg=True)
-    nu = rcurve_transverse(latmid, ell, deg=True)
+    rho = rcurve.meridian(latmid, ell, deg=True)
+    nu = rcurve.transverse(latmid, ell, deg=True)
 
     az = radians(az)
     den = rho * sin(az) ** 2 + nu * cos(az) ** 2
@@ -141,9 +141,7 @@ def rsphere_euler(
     return rho * nu / den
 
 
-def rsphere_curve(
-    lat: float, ell: Ellipsoid = None, deg: bool = True, method: str = "mean"
-) -> float:
+def curve(lat: float, ell: Ellipsoid = None, deg: bool = True, method: str = "mean") -> float:
     """computes the arithmetic average of the transverse and meridional
     radii of curvature at a specified latitude point
 
@@ -167,18 +165,18 @@ def rsphere_curve(
     if deg:
         lat = radians(lat)
 
-    rho = rcurve_meridian(lat, ell, deg=False)
-    nu = rcurve_transverse(lat, ell, deg=False)
+    rho = rcurve.meridian(lat, ell, deg=False)
+    nu = rcurve.transverse(lat, ell, deg=False)
 
     if method == "mean":
         return (rho + nu) / 2
     elif method == "norm":
         return sqrt(rho * nu)
     else:
-        raise Exception("pymap3d.rsphere.curve: method must be mean or norm")
+        raise ValueError("method must be mean or norm")
 
 
-def rsphere_triaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
+def triaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
     """computes triaxial average of the semimajor and semiminor axes of the ellipsoid
 
     Parameters
@@ -202,10 +200,10 @@ def rsphere_triaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
     elif method == "norm":
         return (ell.semimajor_axis ** 2 * ell.semiminor_axis) ** (1 / 3)
     else:
-        raise Exception("pymap3d.rsphere.rsphere_triaxial: method must be mean or norm")
+        raise ValueError("method must be mean or norm")
 
 
-def rsphere_biaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
+def biaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
     """computes biaxial average of the semimajor and semiminor axes of the ellipsoid
 
     Parameters
@@ -229,4 +227,4 @@ def rsphere_biaxial(ell: Ellipsoid = None, method: str = "mean") -> float:
     elif method == "norm":
         return sqrt(ell.semimajor_axis * ell.semiminor_axis)
     else:
-        raise Exception("pymap3d.rsphere.rsphere_biaxial: method must be mean or norm")
+        raise ValueError("method must be mean or norm")


=====================================
src/pymap3d/tests/test_geodetic.py
=====================================
@@ -55,6 +55,38 @@ def test_3d_ecef2geodetic():
     assert [lat, lon, alt] == approx(lla0, rel=1e-4)
 
 
+def test_array_ecef2geodetic():
+    """
+    tests ecef2geodetic can handle numpy array data in addition to singular floats
+    """
+    np = pytest.importorskip("numpy")
+    # test values with no points inside ellipsoid
+    lla0_array = (
+        np.array([lla0[0], lla0[0]]),
+        np.array([lla0[1], lla0[1]]),
+        np.array([lla0[2], lla0[2]]),
+    )
+    xyz = pm.geodetic2ecef(*lla0_array)
+    lats, lons, alts = pm.ecef2geodetic(*xyz)
+
+    assert lats == approx(lla0_array[0])
+    assert lons == approx(lla0_array[1])
+    assert alts == approx(lla0_array[2])
+
+    # test values with some (but not all) points inside ellipsoid
+    lla0_array_inside = (
+        np.array([lla0[0], lla0[0]]),
+        np.array([lla0[1], lla0[1]]),
+        np.array([lla0[2], -lla0[2]]),
+    )
+    xyz = pm.geodetic2ecef(*lla0_array_inside)
+    lats, lons, alts = pm.ecef2geodetic(*xyz)
+
+    assert lats == approx(lla0_array_inside[0])
+    assert lons == approx(lla0_array_inside[1])
+    assert alts == approx(lla0_array_inside[2])
+
+
 def test_xarray():
     xarray = pytest.importorskip("xarray")
     xr_lla = xarray.DataArray(list(lla0))


=====================================
src/pymap3d/tests/test_latitude.py
=====================================
@@ -2,7 +2,8 @@ import pytest
 from pytest import approx
 from math import radians, inf
 
-import pymap3d as pm
+import pymap3d.latitude as latitude
+import pymap3d.rcurve as rcurve
 
 
 @pytest.mark.parametrize(
@@ -10,16 +11,16 @@ import pymap3d as pm
     [(0, 0, 0), (90, 0, 90), (-90, 0, -90), (45, 0, 44.80757678), (-45, 0, -44.80757678)],
 )
 def test_geodetic_alt_geocentric(geodetic_lat, alt_m, geocentric_lat):
-    assert pm.geod2geoc(geodetic_lat, alt_m) == approx(geocentric_lat)
+    assert latitude.geod2geoc(geodetic_lat, alt_m) == approx(geocentric_lat)
 
-    r = pm.geocentric_radius(geodetic_lat)
-    assert pm.geoc2geod(geocentric_lat, r) == approx(geodetic_lat)
-    assert pm.geoc2geod(geocentric_lat, 1e5 + r) == approx(
-        pm.geocentric2geodetic(geocentric_lat, 1e5 + alt_m)
+    r = rcurve.geocentric_radius(geodetic_lat)
+    assert latitude.geoc2geod(geocentric_lat, r) == approx(geodetic_lat)
+    assert latitude.geoc2geod(geocentric_lat, 1e5 + r) == approx(
+        latitude.geocentric2geodetic(geocentric_lat, 1e5 + alt_m)
     )
 
-    assert pm.geod2geoc(geodetic_lat, 1e5 + alt_m) == approx(
-        pm.geodetic2geocentric(geodetic_lat, 1e5 + alt_m)
+    assert latitude.geod2geoc(geodetic_lat, 1e5 + alt_m) == approx(
+        latitude.geodetic2geocentric(geodetic_lat, 1e5 + alt_m)
     )
 
 
@@ -29,21 +30,21 @@ def test_geodetic_alt_geocentric(geodetic_lat, alt_m, geocentric_lat):
 )
 def test_geodetic_geocentric(geodetic_lat, geocentric_lat):
 
-    assert pm.geodetic2geocentric(geodetic_lat, 0) == approx(geocentric_lat)
-    assert pm.geodetic2geocentric(radians(geodetic_lat), 0, deg=False) == approx(
+    assert latitude.geodetic2geocentric(geodetic_lat, 0) == approx(geocentric_lat)
+    assert latitude.geodetic2geocentric(radians(geodetic_lat), 0, deg=False) == approx(
         radians(geocentric_lat)
     )
 
-    assert pm.geocentric2geodetic(geocentric_lat, 0) == approx(geodetic_lat)
-    assert pm.geocentric2geodetic(radians(geocentric_lat), 0, deg=False) == approx(
+    assert latitude.geocentric2geodetic(geocentric_lat, 0) == approx(geodetic_lat)
+    assert latitude.geocentric2geodetic(radians(geocentric_lat), 0, deg=False) == approx(
         radians(geodetic_lat)
     )
 
 
 def test_numpy_geodetic_geocentric():
     pytest.importorskip("numpy")
-    assert pm.geodetic2geocentric([45, 0], 0) == approx([44.80757678, 0])
-    assert pm.geocentric2geodetic([44.80757678, 0], 0) == approx([45, 0])
+    assert latitude.geodetic2geocentric([45, 0], 0) == approx([44.80757678, 0])
+    assert latitude.geocentric2geodetic([44.80757678, 0], 0) == approx([45, 0])
 
 
 @pytest.mark.parametrize(
@@ -51,20 +52,24 @@ def test_numpy_geodetic_geocentric():
     [(0, 0), (90, inf), (-90, -inf), (45, 50.227466), (-45, -50.227466), (89, 271.275)],
 )
 def test_geodetic_isometric(geodetic_lat, isometric_lat):
-    isolat = pm.geodetic2isometric(geodetic_lat)
+    isolat = latitude.geodetic2isometric(geodetic_lat)
     assert isolat == approx(isometric_lat)
     assert isinstance(isolat, float)
 
-    assert pm.geodetic2isometric(radians(geodetic_lat), deg=False) == approx(radians(isometric_lat))
+    assert latitude.geodetic2isometric(radians(geodetic_lat), deg=False) == approx(
+        radians(isometric_lat)
+    )
 
-    assert pm.isometric2geodetic(isometric_lat) == approx(geodetic_lat)
-    assert pm.isometric2geodetic(radians(isometric_lat), deg=False) == approx(radians(geodetic_lat))
+    assert latitude.isometric2geodetic(isometric_lat) == approx(geodetic_lat)
+    assert latitude.isometric2geodetic(radians(isometric_lat), deg=False) == approx(
+        radians(geodetic_lat)
+    )
 
 
 def test_numpy_geodetic_isometric():
     pytest.importorskip("numpy")
-    assert pm.geodetic2isometric([45, 0]) == approx([50.227466, 0])
-    assert pm.isometric2geodetic([50.227466, 0]) == approx([45, 0])
+    assert latitude.geodetic2isometric([45, 0]) == approx([50.227466, 0])
+    assert latitude.isometric2geodetic([50.227466, 0]) == approx([45, 0])
 
 
 @pytest.mark.parametrize(
@@ -72,20 +77,24 @@ def test_numpy_geodetic_isometric():
     [(0, 0), (90, 90), (-90, -90), (45, 44.80768406), (-45, -44.80768406), (89, 88.99327)],
 )
 def test_geodetic_conformal(geodetic_lat, conformal_lat):
-    clat = pm.geodetic2conformal(geodetic_lat)
+    clat = latitude.geodetic2conformal(geodetic_lat)
     assert clat == approx(conformal_lat)
     assert isinstance(clat, float)
 
-    assert pm.geodetic2conformal(radians(geodetic_lat), deg=False) == approx(radians(conformal_lat))
+    assert latitude.geodetic2conformal(radians(geodetic_lat), deg=False) == approx(
+        radians(conformal_lat)
+    )
 
-    assert pm.conformal2geodetic(conformal_lat) == approx(geodetic_lat)
-    assert pm.conformal2geodetic(radians(conformal_lat), deg=False) == approx(radians(geodetic_lat))
+    assert latitude.conformal2geodetic(conformal_lat) == approx(geodetic_lat)
+    assert latitude.conformal2geodetic(radians(conformal_lat), deg=False) == approx(
+        radians(geodetic_lat)
+    )
 
 
 def test_numpy_geodetic_conformal():
     pytest.importorskip("numpy")
-    assert pm.geodetic2conformal([45, 0]) == approx([44.80768406, 0])
-    assert pm.conformal2geodetic([44.80768406, 0]) == approx([45, 0])
+    assert latitude.geodetic2conformal([45, 0]) == approx([44.80768406, 0])
+    assert latitude.conformal2geodetic([44.80768406, 0]) == approx([45, 0])
 
 
 @pytest.mark.parametrize(
@@ -93,21 +102,21 @@ def test_numpy_geodetic_conformal():
     [(0, 0), (90, 90), (-90, -90), (45, 44.855682), (-45, -44.855682)],
 )
 def test_geodetic_rectifying(geodetic_lat, rectifying_lat):
-    assert pm.geodetic2rectifying(geodetic_lat) == approx(rectifying_lat)
-    assert pm.geodetic2rectifying(radians(geodetic_lat), deg=False) == approx(
+    assert latitude.geodetic2rectifying(geodetic_lat) == approx(rectifying_lat)
+    assert latitude.geodetic2rectifying(radians(geodetic_lat), deg=False) == approx(
         radians(rectifying_lat)
     )
 
-    assert pm.rectifying2geodetic(rectifying_lat) == approx(geodetic_lat)
-    assert pm.rectifying2geodetic(radians(rectifying_lat), deg=False) == approx(
+    assert latitude.rectifying2geodetic(rectifying_lat) == approx(geodetic_lat)
+    assert latitude.rectifying2geodetic(radians(rectifying_lat), deg=False) == approx(
         radians(geodetic_lat)
     )
 
 
 def test_numpy_geodetic_rectifying():
     pytest.importorskip("numpy")
-    assert pm.geodetic2rectifying([45, 0]) == approx([44.855682, 0])
-    assert pm.rectifying2geodetic([44.855682, 0]) == approx([45, 0])
+    assert latitude.geodetic2rectifying([45, 0]) == approx([44.855682, 0])
+    assert latitude.rectifying2geodetic([44.855682, 0]) == approx([45, 0])
 
 
 @pytest.mark.parametrize(
@@ -115,17 +124,21 @@ def test_numpy_geodetic_rectifying():
     [(0, 0), (90, 90), (-90, -90), (45, 44.87170288), (-45, -44.87170288)],
 )
 def test_geodetic_authalic(geodetic_lat, authalic_lat):
-    assert pm.geodetic2authalic(geodetic_lat) == approx(authalic_lat)
-    assert pm.geodetic2authalic(radians(geodetic_lat), deg=False) == approx(radians(authalic_lat))
+    assert latitude.geodetic2authalic(geodetic_lat) == approx(authalic_lat)
+    assert latitude.geodetic2authalic(radians(geodetic_lat), deg=False) == approx(
+        radians(authalic_lat)
+    )
 
-    assert pm.authalic2geodetic(authalic_lat) == approx(geodetic_lat)
-    assert pm.authalic2geodetic(radians(authalic_lat), deg=False) == approx(radians(geodetic_lat))
+    assert latitude.authalic2geodetic(authalic_lat) == approx(geodetic_lat)
+    assert latitude.authalic2geodetic(radians(authalic_lat), deg=False) == approx(
+        radians(geodetic_lat)
+    )
 
 
 def test_numpy_geodetic_authalic():
     pytest.importorskip("numpy")
-    assert pm.geodetic2authalic([45, 0]) == approx([44.87170288, 0])
-    assert pm.authalic2geodetic([44.87170288, 0]) == approx([45, 0])
+    assert latitude.geodetic2authalic([45, 0]) == approx([44.87170288, 0])
+    assert latitude.authalic2geodetic([44.87170288, 0]) == approx([45, 0])
 
 
 @pytest.mark.parametrize(
@@ -133,43 +146,43 @@ def test_numpy_geodetic_authalic():
     [(0, 0), (90, 90), (-90, -90), (45, 44.9037878), (-45, -44.9037878)],
 )
 def test_geodetic_parametric(geodetic_lat, parametric_lat):
-    assert pm.geodetic2parametric(geodetic_lat) == approx(parametric_lat)
-    assert pm.geodetic2parametric(radians(geodetic_lat), deg=False) == approx(
+    assert latitude.geodetic2parametric(geodetic_lat) == approx(parametric_lat)
+    assert latitude.geodetic2parametric(radians(geodetic_lat), deg=False) == approx(
         radians(parametric_lat)
     )
 
-    assert pm.parametric2geodetic(parametric_lat) == approx(geodetic_lat)
-    assert pm.parametric2geodetic(radians(parametric_lat), deg=False) == approx(
+    assert latitude.parametric2geodetic(parametric_lat) == approx(geodetic_lat)
+    assert latitude.parametric2geodetic(radians(parametric_lat), deg=False) == approx(
         radians(geodetic_lat)
     )
 
 
 def test_numpy_geodetic_parametric():
     pytest.importorskip("numpy")
-    assert pm.geodetic2parametric([45, 0]) == approx([44.9037878, 0])
-    assert pm.parametric2geodetic([44.9037878, 0]) == approx([45, 0])
+    assert latitude.geodetic2parametric([45, 0]) == approx([44.9037878, 0])
+    assert latitude.parametric2geodetic([44.9037878, 0]) == approx([45, 0])
 
 
 @pytest.mark.parametrize("lat", [91, -91])
 def test_badvals(lat):
     # geodetic_isometric is not included on purpose
     with pytest.raises(ValueError):
-        pm.geodetic2geocentric(lat, 0)
+        latitude.geodetic2geocentric(lat, 0)
     with pytest.raises(ValueError):
-        pm.geocentric2geodetic(lat, 0)
+        latitude.geocentric2geodetic(lat, 0)
     with pytest.raises(ValueError):
-        pm.geodetic2conformal(lat)
+        latitude.geodetic2conformal(lat)
     with pytest.raises(ValueError):
-        pm.conformal2geodetic(lat)
+        latitude.conformal2geodetic(lat)
     with pytest.raises(ValueError):
-        pm.geodetic2rectifying(lat)
+        latitude.geodetic2rectifying(lat)
     with pytest.raises(ValueError):
-        pm.rectifying2geodetic(lat)
+        latitude.rectifying2geodetic(lat)
     with pytest.raises(ValueError):
-        pm.geodetic2authalic(lat)
+        latitude.geodetic2authalic(lat)
     with pytest.raises(ValueError):
-        pm.authalic2geodetic(lat)
+        latitude.authalic2geodetic(lat)
     with pytest.raises(ValueError):
-        pm.geodetic2parametric(lat)
+        latitude.geodetic2parametric(lat)
     with pytest.raises(ValueError):
-        pm.parametric2geodetic(lat)
+        latitude.parametric2geodetic(lat)


=====================================
src/pymap3d/tests/test_look_spheroid.py
=====================================
@@ -1,8 +1,10 @@
 import pytest
 from pytest import approx
-import pymap3d as pm
+
 from math import nan
 
+import pymap3d.los as los
+
 
 @pytest.mark.parametrize(
     "az,tilt,lat,lon,sr",
@@ -17,7 +19,7 @@ from math import nan
 def test_losint(az, tilt, lat, lon, sr):
 
     lla0 = (10, -20, 1e3)
-    lat1, lon1, sr1 = pm.lookAtSpheroid(*lla0, az, tilt=tilt)
+    lat1, lon1, sr1 = los.lookAtSpheroid(*lla0, az, tilt=tilt)
 
     nan_ok = True if tilt == 90 else False
 
@@ -32,7 +34,7 @@ def test_losint(az, tilt, lat, lon, sr):
 def test_badval():
 
     with pytest.raises(ValueError):
-        pm.lookAtSpheroid(0, 0, -1, 0, 0)
+        los.lookAtSpheroid(0, 0, -1, 0, 0)
 
 
 def test_array():
@@ -41,7 +43,7 @@ def test_array():
     az = [0.0, 10.0, 125.0]
     tilt = [30.0, 45.0, 90.0]
     lla0 = (42, -82, 200)
-    lat, lon, sr = pm.lookAtSpheroid(*lla0, az, tilt)
+    lat, lon, sr = los.lookAtSpheroid(*lla0, az, tilt)
 
     truth = np.array(
         [


=====================================
src/pymap3d/tests/test_rcurve.py
=====================================
@@ -1,6 +1,8 @@
 import pytest
 from pytest import approx
+
 import pymap3d as pm
+import pymap3d.rcurve as rcurve
 
 ell = pm.Ellipsoid()
 A = ell.semimajor_axis
@@ -10,12 +12,12 @@ A = ell.semimajor_axis
     "lat,curvature", [(0, A), (90, 0), (-90, 0), (45.0, 4517590.87884893), (-45, 4517590.87884893)]
 )
 def test_rcurve_parallel(lat, curvature):
-    assert pm.rcurve_parallel(lat) == approx(curvature, abs=1e-9)
+    assert rcurve.parallel(lat) == approx(curvature, abs=1e-9)
 
 
 def test_numpy_parallel():
     pytest.importorskip("numpy")
-    assert pm.rcurve_parallel([0, 90]) == approx([A, 0], abs=1e-9)
+    assert rcurve.parallel([0, 90]) == approx([A, 0], abs=1e-9)
 
 
 @pytest.mark.parametrize(
@@ -29,14 +31,14 @@ def test_numpy_parallel():
     ],
 )
 def test_rcurve_meridian(lat, curvature):
-    assert pm.rcurve_meridian(lat) == approx(curvature)
+    assert rcurve.meridian(lat) == approx(curvature)
 
 
 def test_numpy_meridian():
     pytest.importorskip("numpy")
-    assert pm.rcurve_meridian([0, 90]) == approx([6335439.327, 6399593.6258])
+    assert rcurve.meridian([0, 90]) == approx([6335439.327, 6399593.6258])
 
 
 def test_numpy_transverse():
     pytest.importorskip("numpy")
-    assert pm.rcurve_transverse([0, 90]) == approx([A, 6399593.626])
+    assert rcurve.transverse([0, 90]) == approx([A, 6399593.626])


=====================================
src/pymap3d/tests/test_rhumb.py
=====================================
@@ -1,11 +1,12 @@
 import pytest
 from pytest import approx
-import pymap3d as pm
+
+import pymap3d.lox as lox
 
 
 @pytest.mark.parametrize("lat,dist", [(0, 0), (90, 10001965.729)])
 def test_meridian_dist(lat, dist):
-    assert pm.meridian_dist(lat) == approx(dist)
+    assert lox.meridian_dist(lat) == approx(dist)
 
 
 @pytest.mark.parametrize(
@@ -23,7 +24,7 @@ def test_meridian_arc(lat1, lat2, arclen):
     meridianarc(deg2rad(40), deg2rad(80), wgs84Ellipsoid)
     """
 
-    assert pm.meridian_arc(lat1, lat2) == approx(arclen)
+    assert lox.meridian_arc(lat1, lat2) == approx(arclen)
 
 
 @pytest.mark.parametrize(
@@ -37,7 +38,7 @@ def test_meridian_arc(lat1, lat2, arclen):
     ],
 )
 def test_departure(lon1, lon2, lat, dist):
-    assert pm.departure(lon1, lon2, lat) == approx(dist)
+    assert lox.departure(lon1, lon2, lat) == approx(dist)
 
 
 @pytest.mark.parametrize(
@@ -57,7 +58,7 @@ def test_loxodrome_inverse(lat1, lon1, lat2, lon2, arclen, az):
     distance('rh', 40, -80, 65, -148, wgs84Ellipsoid)
     azimuth('rh', 40, -80, 65, -148, wgs84Ellipsoid)
     """
-    rhdist, rhaz = pm.loxodrome_inverse(lat1, lon1, lat2, lon2)
+    rhdist, rhaz = lox.loxodrome_inverse(lat1, lon1, lat2, lon2)
 
     assert rhdist == approx(arclen)
     assert rhaz == approx(az)
@@ -67,7 +68,7 @@ def test_loxodrome_inverse(lat1, lon1, lat2, lon2, arclen, az):
 
 def test_numpy_loxodrome_inverse():
     pytest.importorskip("numpy")
-    d, a = pm.loxodrome_inverse([40, 40], [-80, -80], 65, -148)
+    d, a = lox.loxodrome_inverse([40, 40], [-80, -80], 65, -148)
 
     assert d == approx(5248666.209)
     assert a == approx(302.00567)
@@ -85,7 +86,7 @@ def test_numpy_loxodrome_inverse():
     ],
 )
 def test_loxodrome_direct(lat0, lon0, rng, az, lat1, lon1):
-    lat2, lon2 = pm.loxodrome_direct(lat0, lon0, rng, az)
+    lat2, lon2 = lox.loxodrome_direct(lat0, lon0, rng, az)
     assert lat2 == approx(lat1, abs=1e-6)
     assert lon2 == approx(lon1)
     assert isinstance(lat2, float)
@@ -94,7 +95,7 @@ def test_loxodrome_direct(lat0, lon0, rng, az, lat1, lon1):
 
 def test_numpy_loxodrome_direct():
     pytest.importorskip("numpy")
-    lat, lon = pm.loxodrome_direct([40, 40], [-80, -80], [10000, 10000], [30, 30])
+    lat, lon = lox.loxodrome_direct([40, 40], [-80, -80], [10000, 10000], [30, 30])
     assert lat == approx(40.077995)
     assert lon == approx(-79.941414)
 
@@ -102,4 +103,4 @@ def test_numpy_loxodrome_direct():
 @pytest.mark.parametrize("lat,lon", [([0, 45, 90], [0, 45, 90])])
 def test_meanm(lat, lon):
     pytest.importorskip("numpy")
-    assert pm.meanm(lat, lon) == approx([47.26967, 18.460557])
+    assert lox.meanm(lat, lon) == approx([47.26967, 18.460557])


=====================================
src/pymap3d/tests/test_rsphere.py
=====================================
@@ -1,48 +1,51 @@
 import pytest
 from pytest import approx
+
 import pymap3d as pm
+import pymap3d.rsphere as rsphere
+import pymap3d.rcurve as rcurve
 
 ell = pm.Ellipsoid()
 A = ell.semimajor_axis
 
 
 def test_geocentric_radius():
-    assert pm.geocentric_radius(0) == approx(ell.semimajor_axis)
-    assert pm.geocentric_radius(90) == approx(ell.semiminor_axis)
-    assert pm.geocentric_radius(45) == approx(6367490.0)
-    assert pm.geocentric_radius(30) == approx(6372824.0)
+    assert rcurve.geocentric_radius(0) == approx(ell.semimajor_axis)
+    assert rcurve.geocentric_radius(90) == approx(ell.semiminor_axis)
+    assert rcurve.geocentric_radius(45) == approx(6367490.0)
+    assert rcurve.geocentric_radius(30) == approx(6372824.0)
 
 
 @pytest.mark.parametrize("bad_lat", [-91, 91])
 def test_geocentric_radius_badval(bad_lat):
     with pytest.raises(ValueError):
-        pm.geocentric_radius(bad_lat)
+        rcurve.geocentric_radius(bad_lat)
 
 
 def test_rsphere_eqavol():
-    assert pm.rsphere_eqavol() == approx(6371000.8049)
+    assert rsphere.eqavol() == approx(6371000.8049)
 
 
 def test_rsphere_authalic():
-    assert pm.rsphere_authalic() == approx(6371007.1809)
+    assert rsphere.authalic() == approx(6371007.1809)
 
 
 def test_rsphere_rectifying():
-    assert pm.rsphere_rectifying() == approx(6367449.1458)
+    assert rsphere.rectifying() == approx(6367449.1458)
 
 
 def test_rsphere_biaxial():
-    assert pm.rsphere_biaxial() == approx(6367444.657)
+    assert rsphere.biaxial() == approx(6367444.657)
 
 
 def test_rsphere_triaxial():
-    assert pm.rsphere_triaxial() == approx(6371008.77)
+    assert rsphere.triaxial() == approx(6371008.77)
 
 
 def test_rsphere_euler():
-    assert pm.rsphere_euler(42, 82, 44, 100) == approx(6386606.829131)
+    assert rsphere.euler(42, 82, 44, 100) == approx(6386606.829131)
 
 
 def test_numpy_rsphere_euler():
     pytest.importorskip("numpy")
-    assert pm.rsphere_euler([42, 0], [82, 0], 44, 100) == approx([6386606.829131, 6363111.70923164])
+    assert rsphere.euler([42, 0], [82, 0], 44, 100) == approx([6386606.829131, 6363111.70923164])


=====================================
src/pymap3d/utils.py
=====================================
@@ -16,7 +16,7 @@ except ImportError:
     ndarray = typing.Any  # type: ignore
 
     def sign(x: float) -> float:  # type: ignore
-        """ signum function """
+        """signum function"""
         if x < 0:
             y = -1.0
         elif x > 0:


=====================================
src/pymap3d/vdist/__init__.py
=====================================


=====================================
src/pymap3d/vdist/__main__.py
=====================================
@@ -0,0 +1,14 @@
+import argparse
+
+from .. import vincenty
+
+p = argparse.ArgumentParser(description="Vincenty algorithms")
+p.add_argument("lat1", help="latitude1 WGS-84 [degrees]", type=float)
+p.add_argument("lon1", help="longitude1 WGS-84 [degrees]", type=float)
+p.add_argument("lat2", help="latitude2 WGS-84 [degrees]", type=float)
+p.add_argument("lon2", help="longitude2 WGS-84 [degrees]", type=float)
+P = p.parse_args()
+
+dist_m = vincenty.vdist(P.lat1, P.lon1, P.lat2, P.lon2)
+
+print("{:.3f} meters {:.3f} deg azimuth".format(*dist_m))


=====================================
src/pymap3d/vreckon/__init__.py
=====================================


=====================================
src/pymap3d/vreckon/__main__.py
=====================================
@@ -0,0 +1,16 @@
+from .. import vincenty
+import argparse
+
+
+p = argparse.ArgumentParser(
+    description="Given starting latitude, longitude: find final lat,lon for distance and azimuth"
+)
+p.add_argument("lat", help="latitude WGS-84 [degrees]", type=float)
+p.add_argument("lon", help="longitude WGS-84 [degrees]", type=float)
+p.add_argument("range", help="range from start point [meters]", type=float)
+p.add_argument("azimuth", help="clockwise from north: azimuth to start [degrees]", type=float)
+P = p.parse_args()
+
+lat2, lon2 = vincenty.vreckon(P.lat, P.lon, P.range, P.azimuth)
+
+print("lat, lon = ({:.4f}, {:.4f})".format(lat2.item(), lon2.item()))



View it on GitLab: https://salsa.debian.org/debian-gis-team/pymap3d/-/commit/2e27887770fee03a3dac29a4a1322f7967afd46b

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/pymap3d/-/commit/2e27887770fee03a3dac29a4a1322f7967afd46b
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20210817/b0d06afc/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list