MobilApp/lib/services/gpx_exporter.dart

82 lines
2.9 KiB
Dart

import 'dart:io';
import 'package:path_provider/path_provider.dart';
import '../models/track.dart';
import 'track_database.dart';
/// GPX 1.1 fájl generáló.
/// A GPX az összes standard alkalmazással kompatibilis (OsmAnd, Komoot,
/// QGIS, gpsvisualizer.com stb.).
class GpxExporter {
final TrackDatabase _db;
GpxExporter([TrackDatabase? db]) : _db = db ?? TrackDatabase.instance;
/// Elkészíti a GPX fájlt és visszaadja az elérési utat.
Future<String> export(Track track) async {
final points = await _db.getPoints(track.id!);
final xml = _buildGpx(track, points);
final dir = await getExternalStorageDirectory() ??
await getApplicationDocumentsDirectory();
final safeName =
track.name.replaceAll(RegExp(r'[^a-zA-Z0-9_\-]'), '_').toLowerCase();
final file = File('${dir.path}/${safeName}_${track.id}.gpx');
await file.writeAsString(xml, encoding: utf8_encoding);
return file.path;
}
String _buildGpx(Track track, List<TrackPoint> points) {
final buf = StringBuffer();
buf.writeln('<?xml version="1.0" encoding="UTF-8"?>');
buf.writeln('<gpx version="1.1" creator="Terepi Segéd"');
buf.writeln(' xmlns="http://www.topografix.com/GPX/1/1"');
buf.writeln(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"');
buf.writeln(' xsi:schemaLocation="http://www.topografix.com/GPX/1/1 '
'http://www.topografix.com/GPX/1/1/gpx.xsd">');
buf.writeln(' <metadata>');
buf.writeln(' <name>${_esc(track.name)}</name>');
buf.writeln(
' <time>${track.startTime.toUtc().toIso8601String()}</time>');
buf.writeln(' </metadata>');
buf.writeln(' <trk>');
buf.writeln(' <name>${_esc(track.name)}</name>');
buf.writeln(' <desc>Forrás: ${_esc(track.source)}, '
'${track.pointCount} pont, '
'${track.distanceFormatted}</desc>');
buf.writeln(' <trkseg>');
for (final pt in points) {
buf.write(' <trkpt lat="${pt.latitude}" lon="${pt.longitude}">');
if (pt.altitude != null) {
buf.write('<ele>${pt.altitude!.toStringAsFixed(3)}</ele>');
}
buf.write('<time>${pt.timestamp.toUtc().toIso8601String()}</time>');
if (pt.speed != null) {
buf.write('<speed>${pt.speed!.toStringAsFixed(2)}</speed>');
}
if (pt.heading != null) {
buf.write('<course>${pt.heading!.toStringAsFixed(1)}</course>');
}
if (pt.accuracy != null) {
buf.write('<hdop>${pt.accuracy!.toStringAsFixed(2)}</hdop>');
}
buf.writeln('</trkpt>');
}
buf.writeln(' </trkseg>');
buf.writeln(' </trk>');
buf.writeln('</gpx>');
return buf.toString();
}
String _esc(String s) => s
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;');
}
// ignore: non_constant_identifier_names
final utf8_encoding = const SystemEncoding();