import type maplibregl from 'maplibre-gl' import type { ViewportBounds, VesselPosition } from '../types' /** 맵 인스턴스에서 현재 뷰포트 바운드 추출 */ export function getViewportBounds(map: maplibregl.Map): ViewportBounds { const bounds = map.getBounds() return { west: bounds.getWest(), south: bounds.getSouth(), east: bounds.getEast(), north: bounds.getNorth(), } } /** 바운드 내부에 있는 선박만 필터링 */ export function filterByViewport( positions: T[], bounds: ViewportBounds, ): T[] { return positions.filter( (p) => p.lon >= bounds.west && p.lon <= bounds.east && p.lat >= bounds.south && p.lat <= bounds.north, ) } /** 바운드를 마진(비율)만큼 확장 */ export function expandBounds(bounds: ViewportBounds, margin = 0.1): ViewportBounds { const lonSpan = bounds.east - bounds.west const latSpan = bounds.north - bounds.south return { west: bounds.west - lonSpan * margin, south: bounds.south - latSpan * margin, east: bounds.east + lonSpan * margin, north: bounds.north + latSpan * margin, } } /** VesselPosition 배열의 전체 바운드 계산 (fitBounds용) */ export function calcPositionBounds(positions: VesselPosition[]): ViewportBounds | null { if (positions.length === 0) return null let west = Infinity, south = Infinity, east = -Infinity, north = -Infinity for (const p of positions) { if (p.lon < west) west = p.lon if (p.lon > east) east = p.lon if (p.lat < south) south = p.lat if (p.lat > north) north = p.lat } return { west, south, east, north } }