fix: 智能坐标列检测 — proj_x/proj_y 优先 + 双列名输出

问题: CSV 中 UTM 米坐标被命名为 longitude/latitude,
  列名与实际内容不符, 容易引发 CRS 配置错误。

修复:

1. map.py read_csv_data: 优先级智能列检测
   proj_x/proj_y → longitude/latitude → lon/lat → x_coord/y_coord
   → 终极回退按位置[0][1]。新旧文件全部兼容。

2. csv_processor.py: 输出双列名
   proj_x + proj_y (新标准, 优先)
   longitude + latitude (旧标准, 兼容)
   值完全相同, 新旧代码都能正确读取
This commit is contained in:
duxin
2026-07-08 16:50:20 +08:00
parent f996353b37
commit 830589c108
2 changed files with 33 additions and 6 deletions

View File

@ -233,6 +233,8 @@ class WaterIndexCsvProcessor:
print(f"[WaterIndexCsvProcessor] {name}: 替换 {n_inf} 个 inf/-inf → NaN")
# ===== P0 防御结束 =====
out_df = pd.DataFrame({
"proj_x": df["longitude"].values,
"proj_y": df["latitude"].values,
"longitude": df["longitude"].values,
"latitude": df["latitude"].values,
name: per_idx.values,

View File

@ -876,16 +876,41 @@ class ContentMapper:
print("正在读取CSV文件...")
df = pd.read_csv(csv_file, encoding='utf-8')
# 假设前三列分别是经度、纬度、含量
if df.shape[1] < 3:
raise ValueError("CSV文件必须至少包含3列经度、纬度、含量")
# 获取列名
lon_col = df.columns[0]
lat_col = df.columns[1]
content_col = df.columns[2]
# ── 智能坐标列检测:按优先级匹配,兼容新旧格式 ──
# 优先级: proj_x/proj_y > longitude/latitude > x_coord/y_coord
_COORD_CANDIDATES = [
('proj_x', 'proj_y'),
('longitude', 'longitude'), # 单数形式
('longitude', 'latitude'),
('lon', 'lat'),
('x_coord', 'y_coord'),
]
lon_col, lat_col = None, None
for x_cand, y_cand in _COORD_CANDIDATES:
if x_cand in df.columns and y_cand in df.columns:
lon_col, lat_col = x_cand, y_cand
break
print(f"检测到列名:经度({lon_col}),纬度({lat_col}),含量({content_col})")
if lon_col is None:
# 终极回退:按位置取前两列
lon_col, lat_col = df.columns[0], df.columns[1]
print(f" ⚠ 未识别到标准坐标列名,按位置回退: "
f"X={lon_col}, Y={lat_col}")
# 含量列:跳过坐标列后的第一列
coord_cols = {lon_col, lat_col}
content_col = None
for c in df.columns:
if c not in coord_cols and not c.startswith('pixel_'):
content_col = c
break
if content_col is None:
content_col = df.columns[2]
print(f"检测到列名X({lon_col})Y({lat_col}),含量({content_col})")
# 自动检测不确定性列
if uncertainty_col is None: