Kitűzés: kényelmi funkciók, pontok listája, export
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
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)' : ''}',
|
||||
));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user