import { File, Directory, Paths } from 'expo-file-system'; import { TrackPoint } from '../types'; function recordingsDir(): Directory { return new Directory(Paths.document, 'recordings'); } export function ensureRecordingsDir(): void { const dir = recordingsDir(); if (!dir.exists) dir.create(); } export function saveGpx(trackPoints: TrackPoint[], title: string): string { ensureRecordingsDir(); const filename = `${sanitizeFilename(title)}_${Date.now()}.gpx`; const file = new File(recordingsDir(), filename); file.write(buildGpx(trackPoints, title)); return file.uri; } export function buildGpx(trackPoints: TrackPoint[], title: string): string { const trkpts = trackPoints.map(buildTrkpt).join('\n'); return ` ${escapeXml(title)} ${escapeXml(title)} ${trkpts} `; } function buildTrkpt(pt: TrackPoint): string { const ext = buildExtensions(pt); return ` ${pt.ele.toFixed(1)} ${ext} `; } function buildExtensions(pt: TrackPoint): string { if (pt.hr == null && pt.power == null && pt.cad == null) return ''; const hr = pt.hr != null ? `${pt.hr}` : ''; const power = pt.power != null ? `${pt.power}` : ''; const cad = pt.cad != null ? `${pt.cad}` : ''; return ` ${hr}${power}${cad} `; } export async function parseGpxFile(fileUri: string): Promise { const content = await new File(fileUri).text(); const points: TrackPoint[] = []; const re = /([\s\S]*?)<\/trkpt>/g; let m; while ((m = re.exec(content)) !== null) { const lat = parseFloat(m[1]); const lon = parseFloat(m[2]); const inner = m[3]; const ele = parseFloat(inner.match(/([\d.-]+)<\/ele>/)?.[1] ?? '0'); const timeStr = inner.match(/