76 lines
2.7 KiB
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('&', '&')
|
|
.replaceAll('<', '<')
|
|
.replaceAll('>', '>')
|
|
.replaceAll('"', '"')
|
|
.replaceAll("'", ''');
|
|
}
|
|
|
|
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')}';
|
|
}
|
|
}
|