bounds.ts (3045B)
1 import type { GeolocationPoint } from "./types.js"; 2 3 const EARTH_RADIUS = 6371; 4 5 export const compute_bounding_box = ( 6 lat: number, 7 lng: number, 8 distance_km: number 9 ): { 10 nw: GeolocationPoint; 11 ne: GeolocationPoint; 12 se: GeolocationPoint; 13 sw: GeolocationPoint; 14 } => { 15 const deg_to_rad = (deg: number) => deg * (Math.PI / 180); 16 const rad_to_deg = (rad: number) => rad * (180 / Math.PI); 17 18 function destination_point( 19 lat: number, 20 lng: number, 21 bearing: number, 22 distance_km: number 23 ): GeolocationPoint { 24 const lat1 = deg_to_rad(lat); 25 const lon1 = deg_to_rad(lng); 26 const angular_distance = distance_km / EARTH_RADIUS; 27 28 const lat2 = Math.asin( 29 Math.sin(lat1) * Math.cos(angular_distance) 30 + Math.cos(lat1) 31 * Math.sin(angular_distance) 32 * Math.cos(deg_to_rad(bearing)) 33 ); 34 const lon2 = lon1 35 + Math.atan2( 36 Math.sin(deg_to_rad(bearing)) 37 * Math.sin(angular_distance) 38 * Math.cos(lat1), 39 Math.cos(angular_distance) - Math.sin(lat1) * Math.sin(lat2) 40 ); 41 42 return { lat: rad_to_deg(lat2), lng: rad_to_deg(lon2) }; 43 } 44 45 const bearings = [0, 90, 180, 270]; 46 47 const coords = bearings.map((bearing) => 48 destination_point(lat, lng, bearing, distance_km / Math.sqrt(2)) 49 ); 50 51 return { 52 nw: coords[0], 53 ne: coords[1], 54 se: coords[2], 55 sw: coords[3], 56 }; 57 }; 58 59 export const geo_bounds_calc = ( 60 lat: number, 61 lng: number, 62 distance_km: number 63 ): { 64 north: GeolocationPoint; 65 south: GeolocationPoint; 66 east: GeolocationPoint; 67 west: GeolocationPoint; 68 } => { 69 const deg_to_rad = (deg: number) => deg * (Math.PI / 180); 70 const rad_to_deg = (rad: number) => rad * (180 / Math.PI); 71 72 function destination_point( 73 lat: number, 74 lng: number, 75 bearing: number, 76 distance_km: number 77 ): GeolocationPoint { 78 const lat1 = deg_to_rad(lat); 79 const lon1 = deg_to_rad(lng); 80 const angular_distance = distance_km / EARTH_RADIUS; 81 82 const lat2 = Math.asin( 83 Math.sin(lat1) * Math.cos(angular_distance) 84 + Math.cos(lat1) 85 * Math.sin(angular_distance) 86 * Math.cos(deg_to_rad(bearing)) 87 ); 88 const lon2 = lon1 89 + Math.atan2( 90 Math.sin(deg_to_rad(bearing)) 91 * Math.sin(angular_distance) 92 * Math.cos(lat1), 93 Math.cos(angular_distance) - Math.sin(lat1) * Math.sin(lat2) 94 ); 95 96 return { lat: rad_to_deg(lat2), lng: rad_to_deg(lon2) }; 97 } 98 99 return { 100 north: destination_point(lat, lng, 0, distance_km), 101 south: destination_point(lat, lng, 180, distance_km), 102 east: destination_point(lat, lng, 90, distance_km), 103 west: destination_point(lat, lng, 270, distance_km), 104 }; 105 };