aves_mio0.31/lib/utils/tcx_activity_parser.dart.ok
2026-07-18 13:39:22 +02:00

62 lines
1.6 KiB
Text

import 'package:xml/xml.dart';
import 'package:latlong2/latlong.dart';
import 'package:aves/model/activity/activity_track.dart';
import 'gps_smoothing.dart';
class TcxActivityParser {
static ActivityTrack parse(String xml, {required String fileName}) {
final doc = XmlDocument.parse(xml);
final points = <LatLng>[];
final elevations = <double?>[];
final times = <DateTime?>[];
final trackpoints = doc.findAllElements('Trackpoint');
for (final tp in trackpoints) {
final lat = tp.findElements('LatitudeDegrees')
.map((e) => double.tryParse(e.text))
.firstOrNull;
final lon = tp.findElements('LongitudeDegrees')
.map((e) => double.tryParse(e.text))
.firstOrNull;
final ele = tp.findElements('AltitudeMeters')
.map((e) => double.tryParse(e.text))
.firstOrNull;
final time = tp.findElements('Time')
.map((e) => DateTime.tryParse(e.text))
.firstOrNull;
if (lat != null && lon != null) {
points.add(LatLng(lat, lon));
elevations.add(ele);
times.add(time);
}
}
final smoothed = GpsSmoothing.douglasPeucker(points, 5.0);
return ActivityTrack(
name: fileName,
format: 'TCX',
tracks: {smoothed},
pointCount: smoothed.length,
distanceMeters: null,
elevationGainMeters: null,
duration: null,
startTime: times.firstOrNull,
sport: null,
);
}
}
extension _FirstOrNull<E> on Iterable<E> {
E? get firstOrNull {
final it = iterator;
if (!it.moveNext()) return null;
return it.current;
}
}