meshcore-open/lib/utils/gpx_export.dart
2026-02-22 06:54:27 -08:00

184 lines
4.6 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/foundation.dart';
import 'package:gpx/gpx.dart';
import 'package:meshcore_open/connector/meshcore_connector.dart';
import 'package:meshcore_open/connector/meshcore_protocol.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import '../utils/platform_info.dart';
import 'package:share_plus/share_plus.dart';
class ContactExport {
final String name;
final double lat;
final double lon;
final String desc;
final double? ele;
ContactExport({
required this.name,
required this.lat,
required this.lon,
required this.desc,
this.ele,
});
}
const int gpxExportFailed = -1;
const int gpxExportSuccess = 1;
const int gpxExportNoContacts = 2;
const int gpxExportCancelled = 3;
const int gpxExportNotAvailable = 4;
class GpxExport {
final MeshCoreConnector _connector;
final List<ContactExport> _contacts = [];
GpxExport(this._connector);
void _addContact(
String name,
double lat,
double lon,
String desc, [
double? ele,
]) {
_contacts.add(
ContactExport(
name: name.trim(),
lat: lat,
lon: lon,
desc: desc.trim(),
ele: ele,
),
);
}
void addRepeaters() {
final contacts = _connector.contacts
.where((c) => c.type == advTypeRepeater || c.type == advTypeRoom)
.toList();
for (var contact in contacts) {
if (contact.latitude == null || contact.longitude == null) {
continue;
}
_addContact(
contact.name,
contact.latitude!,
contact.longitude!,
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
);
}
}
void addContacts() {
final contacts = _connector.contacts
.where((c) => c.type == advTypeChat)
.toList();
for (var contact in contacts) {
if (contact.latitude == null || contact.longitude == null) {
continue;
}
_addContact(
contact.name,
contact.latitude!,
contact.longitude!,
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
);
}
}
void addAll() {
final contacts = _connector.contacts;
for (var contact in contacts.toList()) {
if (contact.latitude == null || contact.longitude == null) {
continue;
}
_addContact(
contact.name,
contact.latitude ?? 0.0,
contact.longitude ?? 0.0,
"Type: ${contact.typeLabel}\nPublic Key: ${contact.publicKeyHex}",
);
}
}
Future<int> exportGPX(
String name,
String description,
String filename,
String shareText,
String subject,
) async {
if (PlatformInfo.isWeb) {
debugPrint("GPX export is not supported on Web.");
return gpxExportNotAvailable;
}
if (_contacts.isEmpty) {
debugPrint("No repeaters to export nothing to share.");
return gpxExportNoContacts;
}
try {
// 1. Build GPX content (your existing logic unchanged here)
final gpx = Gpx()
..version = '1.1'
..creator = 'meshcore-open exporter'
..metadata = Metadata(
name: name,
desc: description,
time: DateTime.now().toUtc(),
);
gpx.wpts = _contacts
.map(
(c) => Wpt(
lat: c.lat,
lon: c.lon,
ele: c.ele,
name: c.name,
desc: c.desc,
),
)
.toList();
final xml = GpxWriter().asString(gpx, pretty: true);
// 2. Save to file
final dir = await getApplicationDocumentsDirectory();
final timestamp = DateTime.now()
.toUtc()
.toIso8601String()
.replaceAll(':', '-')
.replaceAll('.', '-')
.split('T')
.join('_');
final path = '${dir.path}/$filename$timestamp.gpx';
final file = File(path);
await file.writeAsString(xml);
final result = await SharePlus.instance.share(
ShareParams(text: shareText, subject: subject, files: [XFile(path)]),
);
await file.delete();
switch (result.status) {
case ShareResultStatus.success:
debugPrint('Share successful user completed the action.');
return gpxExportSuccess;
case ShareResultStatus.dismissed:
debugPrint('Share sheet was dismissed / cancelled by user.');
return gpxExportCancelled;
case ShareResultStatus.unavailable:
debugPrint('Sharing is not available on this platform / context.');
return gpxExportNotAvailable;
}
} catch (e, stack) {
debugPrint('Export or share failed: $e\n$stack');
}
return gpxExportFailed;
}
}