Files

144 lines
4.0 KiB
Dart
Raw Permalink Normal View History

import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import '../../models/stakeout_point.dart';
/// Kitűzési jegyzőkönyv CSV-export.
///
/// Két dialektus:
/// * MAGYAR (Excel-barát): pontosvessző elválasztó, tizedesVESSZŐ,
/// UTF-8 BOM-mal (enélkül az Excel elrontja az ékezeteket)
/// * NEMZETKÖZI: vessző elválasztó, tizedespont
///
/// A jegyzőkönyv a teljes dokumentációt tartalmazza: terv- ÉS mért
/// koordináták, inline/crossline/dZ eltérések, fix-minőség, pontosság,
/// időpont, eszköz, valamint az eltolt pontoknál az eltolás-vektor.
class StakeoutExportService {
StakeoutExportService._();
static Future<void> exportAndShare({
required List<StakeoutPoint> points,
required bool hungarian,
required bool stakedOnly,
String projectName = '',
}) async {
final rows = stakedOnly
? points.where((p) => p.status == StakeoutStatus.staked).toList()
: List.of(points);
if (rows.isEmpty) {
throw StateError('Nincs exportálható pont.');
}
rows.sort((a, b) => a.lineId != b.lineId
? a.lineId.compareTo(b.lineId)
: a.station.compareTo(b.station));
final sep = hungarian ? ';' : ',';
String num(double? v, [int dec = 3]) {
if (v == null) return '';
final s = v.toStringAsFixed(dec);
return hungarian ? s.replaceAll('.', ',') : s;
}
String txt(String s) =>
s.contains(sep) || s.contains('"') || s.contains('\n')
? '"${s.replaceAll('"', '""')}"'
: s;
String status(StakeoutStatus s) => switch (s) {
StakeoutStatus.pending => 'varakozik',
StakeoutStatus.staked => 'kituzve',
StakeoutStatus.skipped => 'kihagyva',
};
String fix(int? q) => switch (q) {
4 => 'RTK_FIXED',
5 => 'RTK_FLOAT',
2 => 'DGPS',
1 => 'GPS',
0 => 'NO_FIX',
null => '',
_ => 'Q$q',
};
final header = [
'Vonal',
'Allomas',
'Nev',
'Tipus',
'Statusz',
'Terv_EOV_Y',
'Terv_EOV_X',
'Terv_EOV_Z',
'Mert_EOV_Y',
'Mert_EOV_X',
'Mert_EOV_Z',
'Inline_m',
'Crossline_m',
'dZ_m',
'Fix',
'Pontossag_m',
'Kituzes_ideje',
'Eltolt',
'Eltolas_m',
'Eltolas_irany_fok',
'Eszkoz_id',
'Forras',
].join(sep);
final sb = StringBuffer();
sb.write('\uFEFF'); // UTF-8 BOM — az Excel enélkül elrontja az ékezeteket
sb.writeln(header);
for (final r in rows) {
sb.writeln([
txt(r.lineId),
r.station.toString(),
txt(r.name),
txt(r.pointType),
status(r.status),
num(r.planEovY),
num(r.planEovX),
num(r.planEovZ),
num(r.measuredEovY),
num(r.measuredEovX),
num(r.measuredEovZ),
num(r.devInline),
num(r.devCrossline),
num(r.devDz),
fix(r.fixQuality),
num(r.accuracy, 2),
r.stakedAt?.toIso8601String() ?? '',
r.isOffset ? '1' : '0',
num(r.offsetDist, 2),
num(r.offsetBearing, 1),
txt(r.deviceId ?? ''),
txt(r.source),
].join(sep));
}
final dir = await getTemporaryDirectory();
final stamp = DateTime.now()
.toIso8601String()
.substring(0, 16)
.replaceAll(':', '')
.replaceAll('-', '')
.replaceAll('T', '_');
final safeName = projectName.isEmpty
? 'kituzes'
: projectName.replaceAll(RegExp(r'[^\w\-]'), '_');
final path = p.join(dir.path, '${safeName}_$stamp.csv');
await File(path).writeAsString(sb.toString(), flush: true);
await SharePlus.instance.share(ShareParams(
files: [XFile(path, mimeType: 'text/csv')],
subject: 'Kitűzési jegyzőkönyv — $projectName',
text: '${rows.length} pont'
'${stakedOnly ? ' (csak kitűzöttek)' : ''}',
));
}
}