MotorSignal-App/lib/services/export_service.dart

81 lines
3.2 KiB
Dart

import 'dart:io';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:drift/drift.dart' hide DatabaseConnectionUser;
import '../database/database.dart';
class ExportService {
final AppDatabase _db;
ExportService(this._db);
Future<void> exportRide(int rideId, {bool asGpx = true}) async {
final telemetry = await (_db.select(_db.telemetrySamples)
..where((t) => t.rideId.equals(rideId))
..orderBy([(t) => OrderingTerm(expression: t.timestamp)])
).get();
if (telemetry.isEmpty) return;
final dir = await getTemporaryDirectory();
if (asGpx) {
final file = File('${dir.path}/ride_$rideId.gpx');
await file.writeAsString(_generateGpx(telemetry));
// ignore: deprecated_member_use
await Share.shareXFiles([XFile(file.path)], text: 'My Motorcycle Ride (GPX)');
} else {
final file = File('${dir.path}/ride_$rideId.csv');
await file.writeAsString(_generateCsv(telemetry));
// ignore: deprecated_member_use
await Share.shareXFiles([XFile(file.path)], text: 'My Motorcycle Ride (CSV)');
}
}
String _generateGpx(List<TelemetrySample> telemetry) {
final sb = StringBuffer();
sb.writeln('<?xml version="1.0" encoding="UTF-8"?>');
sb.writeln('<gpx version="1.1" creator="MotorcycleDash">');
sb.writeln(' <trk>');
sb.writeln(' <name>Ride</name>');
sb.writeln(' <trkseg>');
for (final t in telemetry) {
if (t.latitude != null && t.longitude != null) {
sb.writeln(' <trkpt lat="${t.latitude}" lon="${t.longitude}">');
if (t.altitude != null) {
sb.writeln(' <ele>${t.altitude}</ele>');
}
sb.writeln(' <time>${t.timestamp.toUtc().toIso8601String()}</time>');
// Extend GPX with our custom data
sb.writeln(' <extensions>');
sb.writeln(' <speed>${t.speed ?? 0}</speed>');
sb.writeln(' <heading>${t.heading ?? 0}</heading>');
sb.writeln(' <lean>${t.leanAngle ?? 0}</lean>');
sb.writeln(' <longitudinalG>${t.longitudinalG ?? 0}</longitudinalG>');
sb.writeln(' <lateralG>${t.lateralG ?? 0}</lateralG>');
sb.writeln(' </extensions>');
sb.writeln(' </trkpt>');
}
}
sb.writeln(' </trkseg>');
sb.writeln(' </trk>');
sb.writeln('</gpx>');
return sb.toString();
}
String _generateCsv(List<TelemetrySample> telemetry) {
final sb = StringBuffer();
sb.writeln('timestamp,latitude,longitude,altitude,speed,heading,leanAngle,pitchAngle,accelX,accelY,accelZ,longitudinalG,lateralG');
for (final t in telemetry) {
sb.writeln('${t.timestamp.toIso8601String()},${t.latitude ?? ""},${t.longitude ?? ""},${t.altitude ?? ""},${t.speed ?? ""},${t.heading ?? ""},${t.leanAngle ?? ""},${t.pitchAngle ?? ""},${t.accelX ?? ""},${t.accelY ?? ""},${t.accelZ ?? ""},${t.longitudinalG ?? ""},${t.lateralG ?? ""}');
}
return sb.toString();
}
}
final exportServiceProvider = Provider<ExportService>((ref) {
final db = ref.watch(databaseProvider);
return ExportService(db);
});