import type { LayerAssetState } from "./ir"; export type ImageBounds = [west: number, south: number, east: number, north: number]; export interface DroneExifData { latitude: number; longitude: number; RelativeAltitude: number; ExifImageWidth: number; ExifImageHeight: number; GimbalYawDegree: number; GimbalPitchDegree: number; GimbalRollDegree: number; FocalLength?: number; Make?: string; Model?: string; GPSAltitude?: number; } export interface DroneImageMetadata { /** Normalized source metadata. GPS remains the camera position, not the pitch-adjusted footprint center. */ exifData: DroneExifData; sourceCenter: [longitude: number, latitude: number]; adjustedCenter: [longitude: number, latitude: number]; gsdX: number; gsdY: number; fovDegrees: number; sensorWidthMm: number; sensorHeightMm: number; nonNadir: boolean; pixelRotationDegrees: number; } export interface ResolveImageOverlayOptions { /** Manual camera overrides for models absent from the bundled database. Width and height must be supplied together. */ sensorWidthMm?: number; sensorHeightMm?: number; /** Overrides EXIF FocalLength. No guessed focal-length fallback is used. */ focalLengthMm?: number; } export interface ResolvedImageOverlay { /** Original JPEG when no pixel transform was needed; otherwise a transparency-preserving PNG. */ image: Blob; bounds: ImageBounds; metadata: DroneImageMetadata; } export interface DroneSensorDimensions { widthMm: number; heightMm: number; } /** * PlanetGPT's stage-1 camera roster. Pixel pitch was present in its tuple but * never participates in FOV/GSD, so this contract retains only used values. */ export declare const DRONE_SENSOR_DATABASE: Readonly>; /** Normalize exifr's permissive output into the serializable contract used by all later stages. */ export declare function normalizeDroneExif(rawValue: unknown): DroneExifData; export declare function determineDroneFovDegrees(exif: DroneExifData, options?: ResolveImageOverlayOptions): { fovDegrees: number; sensor: DroneSensorDimensions; focalLengthMm: number; }; /** PlanetGPT-compatible non-nadir center approximation. */ export declare function adjustCenterForPitch(latitude: number, longitude: number, altitude: number, pitch: number, yaw: number): { latitude: number; longitude: number; }; /** PlanetGPT-compatible yaw-expanded, north-aligned WGS84 footprint. */ export declare function calculateDroneFootprint(latitude: number, longitude: number, altitude: number, yaw: number, imageWidth: number, imageHeight: number, diagonalFovDegrees: number): { bounds: ImageBounds; gsdX: number; gsdY: number; }; /** * Public one-shot resolver. Hosts with persistence upload `image`, store * `bounds` + `metadata`, and reconstruct later with explicit bounds so * collaborators/reloads never re-read EXIF. */ export declare function resolveImageOverlay(input: string | Blob, options?: ResolveImageOverlayOptions): Promise; /** * Shared synchronous IR bridge for DOM and programmatic front ends. It starts * one async resolution, returns a pending placeholder, and asks every waiting * map/controller to reconcile once the cached result settles. */ export declare function resolveImageOverlayProps(props: Record, onLoaded: () => void, snapshot?: boolean): LayerAssetState; /** @internal Test isolation; URL caches otherwise intentionally live for the page, like Data Layer URL caches. */ export declare function resetImageOverlayCacheForTests(): void;