Files
mayihua e9f87fc693 feat: CoordConverter 坐标转换套件 v1.0.0
TXT / Excel(CSV) / SHP 三种格式任意互转
支持 WGS84 / CGCS2000 / Xian80 / Beijing54 / Web Mercator 坐标系转换

由 Mapo 🗺️ 自动生成
2026-07-29 12:49:08 +08:00

73 lines
2.4 KiB
Python

"""
Excel/CSV file reader/writer using pandas + openpyxl.
"""
import os
from pathlib import Path
import pandas as pd
from core.data_model import CoordData, CoordPoint
class ExcelHandler:
EXTENSIONS = {".xlsx", ".xls", ".csv"}
@classmethod
def read(cls, path: str, sheet: str | None = None) -> CoordData:
ext = Path(path).suffix.lower()
if ext == ".csv":
df = pd.read_csv(path, encoding="utf-8-sig")
else:
df = pd.read_excel(path, sheet_name=sheet or 0, dtype_backend="numpy_nullable")
if df.empty:
raise ValueError(f"文件无数据: {path}")
records = df.to_dict(orient="records")
# Convert nan to None
for r in records:
for k, v in r.items():
if pd.isna(v):
r[k] = None
cols = list(df.columns)
x_col, y_col, z_col = cls._find_coord_cols(cols)
return CoordData.from_records(records, x_col=x_col, y_col=y_col, z_col=z_col)
@classmethod
def write(cls, data: CoordData, path: str, sheet: str = "坐标数据"):
records = data.to_records()
if not records:
raise ValueError("无数据可写入")
df = pd.DataFrame(records)
ext = Path(path).suffix.lower()
if ext == ".csv":
df.to_csv(path, index=False, encoding="utf-8-sig")
else:
with pd.ExcelWriter(path, engine="openpyxl") as writer:
df.to_excel(writer, sheet_name=sheet, index=False)
@staticmethod
def _find_coord_cols(cols: list[str]) -> tuple[str, str, str | None]:
"""Same logic as TxtHandler for column discovery."""
x_patterns = ["x", "lon", "经度", "lng", "easting"]
y_patterns = ["y", "lat", "纬度", "northing"]
z_patterns = ["z", "h", "高程", "高度", "alt"]
x_col = y_col = z_col = None
lower_cols = {c: c.lower().replace(" ", "").replace("_", "").replace("-","")
for c in cols}
for c, lc in lower_cols.items():
if any(p in lc for p in x_patterns):
x_col = c
elif any(p in lc for p in y_patterns):
y_col = c
elif any(p in lc for p in z_patterns):
z_col = c
if not x_col and len(cols) >= 2:
x_col, y_col = cols[0], cols[1]
return x_col, y_col, z_col