95 lines
2.5 KiB
Python
95 lines
2.5 KiB
Python
from __future__ import annotations
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
TYPE_MAP = {
|
|
"aFLOAT": "R",
|
|
"aBYTE": "B",
|
|
"aSTRING": "S",
|
|
"aCMPLX": "C",
|
|
"aLIST": "L",
|
|
"aWORD10": "W",
|
|
"aLONG": "G",
|
|
"aNotUsed": "?",
|
|
}
|
|
|
|
@dataclass(frozen=True)
|
|
class ObjectDef:
|
|
name: str
|
|
object_id: int
|
|
geometry_code: str
|
|
display_code: str | None
|
|
description: str | None
|
|
raw_line: str
|
|
|
|
@dataclass(frozen=True)
|
|
class AttributeDef:
|
|
name: str
|
|
attribute_id: int
|
|
source_type_name: str
|
|
decoder_type: str
|
|
min_value: float | None
|
|
max_value: float | None
|
|
raw_line: str
|
|
|
|
def _read_lines(path: Path):
|
|
for enc in ("utf-8-sig", "cp1252", "latin1"):
|
|
try:
|
|
return path.read_text(encoding=enc).splitlines()
|
|
except UnicodeDecodeError:
|
|
pass
|
|
raise UnicodeDecodeError("unknown", b"", 0, 1, f"无法读取 {path}")
|
|
|
|
def load_object_dictionary(path: Path) -> list[ObjectDef]:
|
|
out = []
|
|
for line in _read_lines(path):
|
|
if not line.strip():
|
|
continue
|
|
parts = line.rstrip("\r\n").split("|")
|
|
if len(parts) < 3:
|
|
continue
|
|
try:
|
|
object_id = int(parts[1].strip())
|
|
except ValueError:
|
|
continue
|
|
out.append(ObjectDef(
|
|
name=parts[0].strip(),
|
|
object_id=object_id,
|
|
geometry_code=parts[2].strip(),
|
|
display_code=parts[3].strip() if len(parts) > 3 else None,
|
|
description=parts[4].strip() if len(parts) > 4 else None,
|
|
raw_line=line,
|
|
))
|
|
return out
|
|
|
|
def load_attribute_dictionary(path: Path) -> list[AttributeDef]:
|
|
out = []
|
|
for line in _read_lines(path):
|
|
if not line.strip():
|
|
continue
|
|
parts = [p.strip() for p in line.rstrip("\r\n").split("|")]
|
|
if len(parts) < 3:
|
|
continue
|
|
try:
|
|
attribute_id = int(parts[1])
|
|
except ValueError:
|
|
continue
|
|
source_type = parts[2]
|
|
def f(i):
|
|
if len(parts) <= i or parts[i] == "":
|
|
return None
|
|
try:
|
|
return float(parts[i])
|
|
except ValueError:
|
|
return None
|
|
out.append(AttributeDef(
|
|
name=parts[0],
|
|
attribute_id=attribute_id,
|
|
source_type_name=source_type,
|
|
decoder_type=TYPE_MAP.get(source_type, "?"),
|
|
min_value=f(3),
|
|
max_value=f(4),
|
|
raw_line=line,
|
|
))
|
|
return out
|