Kml parser utf-8 támogatás, induláskor minimum app verzió ellenőrzése

This commit is contained in:
2026-07-09 03:43:06 +02:00
parent 1e5601a10b
commit fc31acb80f
8 changed files with 301 additions and 29 deletions
+52 -1
View File
@@ -5,6 +5,7 @@
//
// KMZ = ZIP archív, benne doc.kml
import 'dart:convert';
import 'dart:typed_data';
import 'package:archive/archive.dart';
import 'package:flutter/material.dart';
@@ -17,6 +18,55 @@ import 'package:xml/xml.dart';
import '../models/imported_layer.dart';
class KmlParser {
/// KML szöveg dekódolása a fájlban DEKLARÁLT kódolással (vagy UTF-8,
/// ha nincs deklaráció — ez az XML alapértelmezése).
///
/// * UTF-8 deklaráció (vagy annak hiánya) → UTF-8 dekódolás; ha ez
/// mégis érvénytelen bájtsorozatra futna (rosszul címkézett fájl),
/// Latin-1-re esünk vissza — az minden bájt-értékre ad valamilyen
/// karaktert, nem dob kivételt.
/// * Explicit ISO-8859-1 / Windows-1252 deklaráció → Latin-1.
/// * Egyéb, Dart alapkönyvtára által NEM ismert kódolás (pl.
/// ISO-8859-2, Windows-1250 — ezek adnák helyesen az ő/ű betűket
/// egy esetleges nem-UTF-8 exportnál) → egyértelmű hibaüzenet,
/// ahelyett hogy csendben félrement szöveget adnánk.
static String decodeText(List<int> bytes) {
final declared = _detectDeclaredEncoding(bytes);
if (declared == null ||
declared.contains('utf-8') ||
declared.contains('utf8')) {
try {
return utf8.decode(bytes);
} catch (_) {
return latin1.decode(bytes);
}
}
if (declared.contains('8859-1') ||
declared.contains('latin1') ||
declared.contains('windows-1252') ||
declared.contains('cp1252')) {
return latin1.decode(bytes);
}
if (declared == 'ascii' || declared == 'us-ascii') {
return ascii.decode(bytes, allowInvalid: true);
}
throw FormatException(
'Ismeretlen vagy nem támogatott KML kódolás a fájlban: '
'"$declared". Exportáld a fájlt UTF-8 kódolással.');
}
static String? _detectDeclaredEncoding(List<int> bytes) {
final headLen = bytes.length < 200 ? bytes.length : 200;
final head = ascii.decode(bytes.sublist(0, headLen), allowInvalid: true);
final match =
RegExp(r'''encoding\s*=\s*["']([^"']+)["']''').firstMatch(head);
return match?.group(1)?.toLowerCase();
}
// Alapértelmezett stílusok — felülírhatók konstruktorban
final Color defaultPolylineColor;
final double defaultPolylineStroke;
@@ -46,7 +96,8 @@ class KmlParser {
orElse: () => throw Exception('Nem található .kml fájl a KMZ-ben'),
);
final kmlString = String.fromCharCodes(kmlFile.content as List<int>);
//final kmlString = String.fromCharCodes(kmlFile.content as List<int>);
final kmlString = utf8.decode(kmlFile.content as List<int>);
return _parse(kmlString, fileName, LayerImportSourceType.kmz,
id: id, isVisible: isVisible);
}