import math import numpy as np import polars as pl _EARTH_RADIUS_KM = 6371.0 def haversine_km( lat1: np.ndarray, lon1: np.ndarray, lat2: float, lon2: float ) -> np.ndarray: """Compute haversine distance in km between arrays (lat1, lon1) and a single point (lat2, lon2).""" lat1_rad = np.radians(lat1) lon1_rad = np.radians(lon1) lat2_rad = np.radians(lat2) lon2_rad = np.radians(lon2) dlat = lat2_rad - lat1_rad dlon = lon2_rad - lon1_rad a = ( np.sin(dlat / 2) ** 2 + np.cos(lat1_rad) * np.cos(lat2_rad) * np.sin(dlon / 2) ** 2 ) c = 2 * np.arcsin(np.sqrt(a)) return _EARTH_RADIUS_KM * c def haversine_km_expr( lat_col: str, lon_col: str, dest_lat: float, dest_lon: float ) -> pl.Expr: """Polars expression computing haversine distance in km to a fixed point.""" dest_lat_rad = math.radians(dest_lat) dest_lon_rad = math.radians(dest_lon) lat_rad = pl.col(lat_col).radians() lon_rad = pl.col(lon_col).radians() dlat = pl.lit(dest_lat_rad) - lat_rad dlon = pl.lit(dest_lon_rad) - lon_rad a = (dlat / 2).sin() ** 2 + pl.lit(dest_lat_rad).cos() * lat_rad.cos() * ( dlon / 2 ).sin() ** 2 return 2 * _EARTH_RADIUS_KM * a.sqrt().arcsin()