import {worldToLngLat} from './web-mercator-utils'; import {mod, log2} from './math-utils'; // defined by mapbox-gl const TILE_SIZE = 512; /** Description of viewport */ export type ViewportProps = { width: number; height: number; longitude: number; latitude: number; zoom: number; pitch?: number; bearing?: number; }; /** * Apply mathematical constraints to viewport props * @param props */ // eslint-disable-next-line complexity export function normalizeViewportProps(props: ViewportProps): ViewportProps { const {width, height, pitch = 0} = props; let {longitude, latitude, zoom, bearing = 0} = props; // Normalize degrees if (longitude < -180 || longitude > 180) { longitude = mod(longitude + 180, 360) - 180; } if (bearing < -180 || bearing > 180) { bearing = mod(bearing + 180, 360) - 180; } // Constrain zoom and shift center at low zoom levels const minZoom = log2(height / TILE_SIZE); if (zoom <= minZoom) { zoom = minZoom; latitude = 0; } else { // Eliminate white space above and below the map const halfHeightPixels = height / 2 / Math.pow(2, zoom); const minLatitude = worldToLngLat([0, halfHeightPixels])[1]; if (latitude < minLatitude) { latitude = minLatitude; } else { const maxLatitude = worldToLngLat([0, TILE_SIZE - halfHeightPixels])[1]; if (latitude > maxLatitude) { latitude = maxLatitude; } } } return {width, height, longitude, latitude, zoom, pitch, bearing}; }