144 lines
4.0 KiB
Dart
144 lines
4.0 KiB
Dart
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)' : ''}',
|
||
|
|
));
|
||
|
|
}
|
||
|
|
}
|