Source code for suboptimumg.track.gps

from typing import Any, Tuple

import numpy as np
import numpy.typing as npt
from scipy.interpolate import splev, splprep


[docs] def resample_xy_uniform( x_m: npt.NDArray[np.float64], y_m: npt.NDArray[np.float64], distance_step: float, smoothing: float = 0.0, ) -> Tuple[ npt.NDArray[np.float64], npt.NDArray[np.float64], npt.NDArray[np.float64], Any ]: """ Fit a B-spline through Cartesian XY coordinates and resample at a uniform arc-length spacing. The spline is fit in XY space (not lat/lon) so the resulting points are genuinely equally spaced in meters. Parameters ---------- x_m : NDArray[float64] East coordinates in meters (clean, no NaNs) y_m : NDArray[float64] North coordinates in meters (clean, no NaNs) distance_step : float Desired spacing between output points in meters smoothing : float Spline smoothing factor (0 = interpolating spline) Returns ------- NDArray[float64] x_uniform - Uniformly-spaced East coordinates in meters NDArray[float64] y_uniform - Uniformly-spaced North coordinates in meters NDArray[float64] cumulative_dist - Arc-length distances at each output point (meters) Any tck - Scipy B-spline representation for later evaluation """ x_m = np.asarray(x_m, dtype=np.float64) y_m = np.asarray(y_m, dtype=np.float64) # Remove consecutive duplicates (splprep requires distinct points) dx = np.diff(x_m, prepend=np.nan) dy = np.diff(y_m, prepend=np.nan) step = np.sqrt(dx**2 + dy**2) unique = np.concatenate(([True], step[1:] > 0)) x_m = x_m[unique] y_m = y_m[unique] # Compute arc-length parameterisation from the cleaned points seg_len = np.sqrt(np.diff(x_m) ** 2 + np.diff(y_m) ** 2) arc_length = np.zeros(len(x_m)) arc_length[1:] = np.cumsum(seg_len) total_length = arc_length[-1] tck, _ = splprep([x_m, y_m], u=arc_length, s=smoothing, k=3) num_points = int(np.ceil(total_length / distance_step)) + 1 cumulative_dist = np.linspace(0.0, total_length, num_points) x_uniform, y_uniform = splev(cumulative_dist, tck) return ( np.asarray(x_uniform, dtype=np.float64), np.asarray(y_uniform, dtype=np.float64), cumulative_dist, tck, )