Track, nyomkövetés hozzáadása
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
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('&', '&')
|
||||
.replaceAll('<', '<')
|
||||
.replaceAll('>', '>')
|
||||
.replaceAll('"', '"');
|
||||
}
|
||||
|
||||
// ignore: non_constant_identifier_names
|
||||
final utf8_encoding = const SystemEncoding();
|
||||
Reference in New Issue
Block a user