delivery_app/lib/services/gpx_export.dart

76 lines
2.7 KiB
Dart

import 'dart:io';
import 'package:latlong2/latlong.dart';
import 'package:path_provider/path_provider.dart';
import '../models/stop.dart';
class GpxExportService {
/// Export route stops as GPX file with waypoints and optional track.
/// Returns the file path of the saved GPX file.
static Future<String> exportRoute({
required String routeName,
required List<Stop> stops,
List<LatLng>? trackPoints,
}) async {
final buffer = StringBuffer();
buffer.writeln('<?xml version="1.0" encoding="UTF-8"?>');
buffer.writeln(
'<gpx version="1.1" creator="Delivery Route App" xmlns="http://www.topografix.com/GPX/1/1">');
buffer.writeln(' <metadata>');
buffer.writeln(' <name>${_escapeXml(routeName)}</name>');
buffer.writeln(' <time>${DateTime.now().toUtc().toIso8601String()}</time>');
buffer.writeln(' </metadata>');
// Waypoints
for (final stop in stops) {
buffer.writeln(' <wpt lat="${stop.lat}" lon="${stop.lng}">');
buffer.writeln(' <name>${_escapeXml(stop.street)} ${_escapeXml(stop.houseNumber)}</name>');
if (stop.newspapers.isNotEmpty) {
buffer.writeln(' <desc>${_escapeXml(stop.newspapers.join(', '))}</desc>');
}
if (stop.notes.isNotEmpty) {
buffer.writeln(' <cmt>${_escapeXml(stop.notes)}</cmt>');
}
buffer.writeln(' </wpt>');
}
// Track (if route points available)
if (trackPoints != null && trackPoints.isNotEmpty) {
buffer.writeln(' <trk>');
buffer.writeln(' <name>${_escapeXml(routeName)} - Route</name>');
buffer.writeln(' <trkseg>');
for (final point in trackPoints) {
buffer.writeln(
' <trkpt lat="${point.latitude}" lon="${point.longitude}"></trkpt>');
}
buffer.writeln(' </trkseg>');
buffer.writeln(' </trk>');
}
buffer.writeln('</gpx>');
// Save to file
final directory = await getApplicationDocumentsDirectory();
final sanitized = routeName.replaceAll(RegExp(r'[^\w\s-]'), '').replaceAll(' ', '_');
final fileName = 'route_${sanitized}_${_dateStamp()}.gpx';
final file = File('${directory.path}/$fileName');
await file.writeAsString(buffer.toString());
return file.path;
}
static String _escapeXml(String text) {
return text
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&apos;');
}
static String _dateStamp() {
final now = DateTime.now();
return '${now.year}${now.month.toString().padLeft(2, '0')}${now.day.toString().padLeft(2, '0')}_${now.hour.toString().padLeft(2, '0')}${now.minute.toString().padLeft(2, '0')}';
}
}