Skip to content

Commit

Permalink
vdist, vreckon: add deg= option (default true)
Browse files Browse the repository at this point in the history
track2: correct deg=False radians

pure Python linspace()
  • Loading branch information
scivision committed Nov 26, 2023
1 parent 13cf5d5 commit 343a786
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 78 deletions.
11 changes: 11 additions & 0 deletions src/pymap3d/mathfun.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import from Numpy, and if not available fallback to math stdlib
"""

from __future__ import annotations

try:
from numpy import arcsin as asin
from numpy import arcsinh as asinh
Expand All @@ -17,6 +19,7 @@
inf,
isclose,
isnan,
linspace,
log,
power,
radians,
Expand Down Expand Up @@ -46,6 +49,14 @@
tan,
)

def linspace(start: float, stop: float, num: int) -> list[float]: # type: ignore
"""
create a list of "num" evenly spaced numbers using range and increment,
including endpoint "stop"
"""
step = (stop - start) / (num - 1)
return [start + i * step for i in range(num)]

def power(x, y): # type: ignore
return pow(x, y)

Expand Down
48 changes: 48 additions & 0 deletions src/pymap3d/tests/test_matlab_track2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""
Compare with Matlab Mapping toolbox reckon()
"""

from __future__ import annotations

import pytest
from pytest import approx

try:
import numpy as np
from .matlab_engine import matlab_engine, has_mapping
except ImportError:
pytest.skip("Matlab Engine not found", allow_module_level=True)


import pymap3d.vincenty


def track2(eng, lat1: float, lon1: float, lat2: float, lon2: float, npts: int, deg: bool) -> tuple:
"""Using Matlab Engine to do same thing as Pymap3d"""
d = "degrees" if deg else "radians"

lats, lons = eng.track2(
"gc", lat1, lon1, lat2, lon2, eng.wgs84Ellipsoid(), d, float(npts), nargout=2
)
return np.array(lats).squeeze(), np.array(lons).squeeze()


@pytest.mark.parametrize("deg", [True, False])
def test_track2_compare(deg):
lat1, lon1 = 0.0, 80.0
lat2, lon2 = 0.0, 81.0
if not deg:
lat1, lon1, lat2, lon2 = np.radians((lat1, lon1, lat2, lon2))

eng = matlab_engine()

if not has_mapping(eng):
pytest.skip("Matlab Toolbox not found")

lats, lons = pymap3d.vincenty.track2(lat1, lon1, lat2, lon2, npts=4, deg=deg)

lats_m, lons_m = track2(eng, lat1, lon1, lat2, lon2, npts=4, deg=deg)

assert lats == approx(lats_m)
assert lons == approx(lons_m)
23 changes: 19 additions & 4 deletions src/pymap3d/tests/test_vincenty.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import pymap3d.vincenty as vincenty

import pytest
from pytest import approx


def test_track2():
lats, lons = vincenty.track2(40, 80, 65, -148, npts=3)
assert lats == approx([40, 69.633139886, 65])
assert lons == approx([80, 113.06849104, -148])
@pytest.mark.parametrize("deg", [True, False])
def test_track2_unit(deg):
np = pytest.importorskip("numpy")

lat1, lon1 = 0.0, 80.0
lat2, lon2 = 0.0, 81.0
lat0 = [0.0, 0.0, 0.0, 0.0]
lon0 = [80.0, 80.33333, 80.66666, 81.0]
if not deg:
lat1, lon1, lat2, lon2 = np.radians((lat1, lon1, lat2, lon2))
lat0 = np.radians(lat0)
lon0 = np.radians(lon0)

lats, lons = vincenty.track2(lat1, lon1, lat2, lon2, npts=4, deg=deg)

assert lats == approx(lat0)
assert lons == approx(lon0)
11 changes: 9 additions & 2 deletions src/pymap3d/tests/test_vincenty_vreckon.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from math import radians

import pymap3d.vincenty as vincenty

import pytest
from pytest import approx

Expand All @@ -14,6 +17,7 @@
az3 = (218.00292856, 225.0011203)


@pytest.mark.parametrize("deg", [True, False])
@pytest.mark.parametrize(
"lat,lon,srange,az,lato,lono",
[
Expand All @@ -26,8 +30,11 @@
(0, 0, 2.00375e7, -90, 0, 180),
],
)
def test_unit(lat, lon, srange, az, lato, lono):
lat1, lon1 = vincenty.vreckon(lat, lon, srange, az)
def test_vreckon_unit(deg, lat, lon, srange, az, lato, lono):
if not deg:
lat, lon, az, lato, lono = map(radians, (lat, lon, az, lato, lono))

lat1, lon1 = vincenty.vreckon(lat, lon, srange, az, deg=deg)

assert lat1 == approx(lato)
assert isinstance(lat1, float)
Expand Down
Loading

0 comments on commit 343a786

Please sign in to comment.