UNPKG

licelfile

Version:

A Bun package for reading licel files (from lidar transient recorder)

77 lines (63 loc) 2.99 kB
import { parseLicelProfile } from "./licelprofile"; import { type ILicelFile } from "./licelTypes"; import { latin1Decode, parseDateTime } from "./utils"; const HEADER_LINE_LENGTH = 80; /** * Загружает файл Licel из массива байтов. * @param path - имя файла. * @returns Объект ILicelFile, содержащий данные измерения. */ export async function loadLicelFile(path: string): Promise<ILicelFile> { const rawBuffer = await Bun.file(path).arrayBuffer(); return loadLicelFileFromArrayBuffer(rawBuffer); } /** * Загружает файл Licel из массива байтов. * @param rawBuffer - Массив байтов. * @returns Объект ILicelFile, содержащий данные измерения. */ export async function loadLicelFileFromArrayBuffer(rawBuffer: ArrayBuffer): Promise<ILicelFile> { //const rawBuffer = await Bun.file(path).arrayBuffer(); const view = new DataView(rawBuffer); const header0 = latin1Decode(rawBuffer.slice(0, 80)).trim().split(/\s+/); const header1 = latin1Decode(rawBuffer.slice(80, 160)).trim().split(/\s+/); const header2 = latin1Decode(rawBuffer.slice(160, 240)).trim().split(/\s+/); const measurementStartTime = parseDateTime(`${header1[1]} ${header1[2]}`); const measurementStopTime = parseDateTime(`${header1[3]} ${header1[4]}`); const licelFile: ILicelFile = { measurementSite: header1[0]!, measurementStartTime, measurementStopTime, altitudeAboveSeaLevel: parseFloat(header1[5]!), longitude: parseFloat(header1[6]!), latitude: parseFloat(header1[7]!), zenith: parseFloat(header1[8]!), laserConfig: [{ numberOfShots: parseInt(header2[0]!, 10), frequency: parseInt(header2[1]!, 10) }, { numberOfShots: parseInt(header2[2]!, 10), frequency: parseInt(header2[3]!, 10) }, { numberOfShots: parseInt(header2[5]!, 10), frequency: parseInt(header2[6]!, 10) }], nDatasets: parseInt(header2[4]!, 10), profiles: [], }; for (let i = 0; i < licelFile.nDatasets; i++) { const profileLine = latin1Decode(rawBuffer.slice((3 + i) * HEADER_LINE_LENGTH, (3 + (i + 1)) * HEADER_LINE_LENGTH)).trim(); const profile = parseLicelProfile(profileLine); licelFile.profiles.push(profile); } const bytesoffset = (3 + licelFile.nDatasets) * HEADER_LINE_LENGTH + 2; let offset = bytesoffset; for (let i = 0; i < licelFile.nDatasets; i++) { const profileLen = licelFile.profiles![i]!.nDataPoints * 4; const profileData = rawBuffer.slice(offset, offset + profileLen); const profileDataUInt32 = new Uint32Array(profileData); offset += (profileLen + 2); licelFile.profiles![i]!.data = profileDataUInt32.map((value) => (value / licelFile.profiles![i]!.nShots)); } return licelFile; }