refactor: 中间层消除硬编码波段号+CRS动态探测
- GlintRemovalStep/handler/service 全部改为传递波长参数而非波段索引 - ContentMapper 移除 EPSG:32651 硬编码, 新增 _ensure_crs() + _probe_crs_from_file() - _prepare_shared_context 在 read_csv_data 前先探测边界文件 CRS - GUI QSpinBox→QDoubleSpinBox,默认值改为波长(nm),placeholder 提示自动探测 - 消除 38/36/49/47/25/37/65/91 等所有魔法数字
This commit is contained in:
@ -24,9 +24,9 @@ Step11 后端计算服务(专题图生成 / 克里金插值)
|
||||
"geotiff_dir": "D:/10_WaterIndex_Images", # 批量 GeoTIFF
|
||||
"boundary_shp_path": "D:/boundary.shp", # 边界 shp(可选)
|
||||
"resolution": 30.0, # 空间分辨率(米)
|
||||
"input_crs": "EPSG:32651",
|
||||
# ★★★ 强制默认 output_crs = input_crs,禁止从 service 配置误改为 EPSG:4326 ★★★
|
||||
"output_crs": "EPSG:32651",
|
||||
# CRS 默认留空,由 ContentMapper 从边界/栅格自动探测
|
||||
"input_crs": None,
|
||||
"output_crs": None,
|
||||
"output_dir": "D:/11_Thematic_Map", # 输出目录
|
||||
"enabled": True,
|
||||
"work_dir": "D:/workspace", # 工作目录
|
||||
@ -188,6 +188,13 @@ def _run_geotiff_mode(geotiff_paths: List[Path],
|
||||
from src.postprocessing.map import ContentMapper
|
||||
|
||||
mapper = ContentMapper()
|
||||
# ★ CRS 动态探测:从第一个 GeoTIFF 或边界文件自动获取
|
||||
if geotiff_paths:
|
||||
mapper._ensure_crs(reference_file=str(geotiff_paths[0]))
|
||||
elif boundary_shp_path:
|
||||
mapper._ensure_crs(reference_file=boundary_shp_path)
|
||||
else:
|
||||
mapper._ensure_crs()
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
n_ok = 0
|
||||
for tif_path in geotiff_paths:
|
||||
|
||||
@ -230,6 +230,8 @@ def _try_distribution_maps(work_dir: str, output_dir: Path) -> Dict[str, Any]:
|
||||
from src.postprocessing.map import ContentMapper
|
||||
|
||||
mapper = ContentMapper()
|
||||
# ★ CRS 动态探测:从第一个 GeoTIFF 自动获取
|
||||
mapper._ensure_crs(reference_file=str(tif_paths[0]))
|
||||
for tif_path in tif_paths:
|
||||
stem = tif_path.stem
|
||||
chinese_title = mapper._get_chinese_title(stem)
|
||||
|
||||
@ -19,10 +19,12 @@ Step3 后端计算服务(耀斑去除)
|
||||
"interpolation_method": "bilinear",
|
||||
"water_mask_path": "D:/mask.dat", # 水域掩膜(可选)
|
||||
"output_path": "D:/deglint_image.bsq",
|
||||
# 方法专属参数(按 method 任选一组)
|
||||
"nir_lower": 65, "nir_upper": 91, "goodman_A": 1.9e-5, "goodman_B": 0.1, # goodman
|
||||
"oxy_band": 38, "lower_oxy": 36, "upper_oxy": 49, "nir_band": 47, # kutser
|
||||
"hedley_nir_band": 47, # hedley
|
||||
# 方法专属参数(波长驱动,nm → 自动解析波段号)
|
||||
"nir_lower_wavelength": 641.93, "nir_upper_wavelength": 751.49,
|
||||
"goodman_A": 1.9e-5, "goodman_B": 0.1, # goodman
|
||||
"oxy_wavelength": 760.6, "lower_wavelength": 742.39, # kutser
|
||||
"upper_wavelength": 860.48, "nir_wavelength": 842.36, # kutser
|
||||
"hedley_nir_wavelength": 842.36, # hedley
|
||||
"sugar_iter": 3, "sugar_sigma": 1.0, "sugar_estimate_background": True,
|
||||
"sugar_glint_mask_method": "cdf", "sugar_termination_thresh": 20.0,
|
||||
"sugar_bounds": [(1, 2)], # sugar
|
||||
@ -79,24 +81,24 @@ def _normalize_method(method: str) -> str:
|
||||
|
||||
|
||||
def _build_method_kwargs(method: str, config: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""按 method 从 config 中抽取对应的方法专属参数"""
|
||||
"""按 method 从 config 中抽取对应的方法专属参数(波长驱动)"""
|
||||
if method == "goodman":
|
||||
return {
|
||||
"nir_lower": int(config.get("nir_lower", 65)),
|
||||
"nir_upper": int(config.get("nir_upper", 91)),
|
||||
"nir_lower_wavelength": float(config.get("nir_lower_wavelength", 641.93)),
|
||||
"nir_upper_wavelength": float(config.get("nir_upper_wavelength", 751.49)),
|
||||
"goodman_A": float(config.get("goodman_A", 0.000019)),
|
||||
"goodman_B": float(config.get("goodman_B", 0.1)),
|
||||
}
|
||||
if method == "kutser":
|
||||
return {
|
||||
"oxy_band": int(config.get("oxy_band", 38)),
|
||||
"lower_oxy": int(config.get("lower_oxy", 36)),
|
||||
"upper_oxy": int(config.get("upper_oxy", 49)),
|
||||
"nir_band": int(config.get("nir_band", 47)),
|
||||
"oxy_wavelength": float(config.get("oxy_wavelength", 760.6)),
|
||||
"lower_wavelength": float(config.get("lower_wavelength", 742.39)),
|
||||
"upper_wavelength": float(config.get("upper_wavelength", 860.48)),
|
||||
"nir_wavelength": float(config.get("nir_wavelength", 842.36)),
|
||||
}
|
||||
if method == "hedley":
|
||||
return {
|
||||
"hedley_nir_band": int(config.get("hedley_nir_band", 47)),
|
||||
"hedley_nir_wavelength": float(config.get("hedley_nir_wavelength", 842.36)),
|
||||
}
|
||||
if method == "sugar":
|
||||
bounds = config.get("sugar_bounds")
|
||||
|
||||
@ -177,14 +177,11 @@ class Step11View(BaseView):
|
||||
params_layout.addRow("分辨率(米):", self.resolution)
|
||||
|
||||
self.input_crs = QLineEdit()
|
||||
self.input_crs.setText("EPSG:32651")
|
||||
self.input_crs.setPlaceholderText("留空=从掩膜/栅格自动探测")
|
||||
params_layout.addRow("输入坐标系:", self.input_crs)
|
||||
|
||||
self.output_crs = QLineEdit()
|
||||
# ★★★ 强制默认输出坐标系与输入一致,禁止从 GUI 误改为 EPSG:4326 ★★★
|
||||
# 历史默认值 'EPSG:4326' 会让 ContentMapper 把栅格重投影到经纬度,
|
||||
# 与基于 EPSG:32651 的水域掩膜叠加时发生仿射变换撕裂(栅格错位、坐标轴扭曲)。
|
||||
self.output_crs.setText("EPSG:32651")
|
||||
self.output_crs.setPlaceholderText("留空=与输入坐标系一致")
|
||||
params_layout.addRow("输出坐标系:", self.output_crs)
|
||||
|
||||
self.show_points = QCheckBox("显示采样点")
|
||||
@ -346,9 +343,8 @@ class Step11View(BaseView):
|
||||
self.resolution.setValue(config["resolution"])
|
||||
if "input_crs" in config:
|
||||
self.input_crs.setText(config["input_crs"])
|
||||
# ★★★ 反灌入时强制 output_crs = input_crs,避免旧 config 中的 EPSG:4326 回填 ★★★
|
||||
if "output_crs" in config or "input_crs" in config:
|
||||
self.output_crs.setText(config.get("input_crs") or config.get("output_crs") or "EPSG:32651")
|
||||
self.output_crs.setText(config.get("input_crs") or config.get("output_crs") or "")
|
||||
if "show_sample_points" in config:
|
||||
self.show_points.setChecked(config["show_sample_points"])
|
||||
if "use_distance_diffusion" in config:
|
||||
|
||||
@ -64,14 +64,18 @@ class Step3View(BaseView):
|
||||
# Goodman 参数组
|
||||
self.goodman_group = QGroupBox("Goodman方法参数")
|
||||
goodman_layout = QFormLayout()
|
||||
self.nir_lower = QSpinBox()
|
||||
self.nir_lower.setRange(0, 200)
|
||||
self.nir_lower.setValue(65)
|
||||
goodman_layout.addRow("NIR下波段索引:", self.nir_lower)
|
||||
self.nir_upper = QSpinBox()
|
||||
self.nir_upper.setRange(0, 200)
|
||||
self.nir_upper.setValue(91)
|
||||
goodman_layout.addRow("NIR上波段索引:", self.nir_upper)
|
||||
self.nir_lower_wavelength = QDoubleSpinBox()
|
||||
self.nir_lower_wavelength.setDecimals(2)
|
||||
self.nir_lower_wavelength.setRange(300.0, 3000.0)
|
||||
self.nir_lower_wavelength.setValue(641.93)
|
||||
self.nir_lower_wavelength.setSuffix(" nm")
|
||||
goodman_layout.addRow("NIR下界波长:", self.nir_lower_wavelength)
|
||||
self.nir_upper_wavelength = QDoubleSpinBox()
|
||||
self.nir_upper_wavelength.setDecimals(2)
|
||||
self.nir_upper_wavelength.setRange(300.0, 3000.0)
|
||||
self.nir_upper_wavelength.setValue(751.49)
|
||||
self.nir_upper_wavelength.setSuffix(" nm")
|
||||
goodman_layout.addRow("NIR上界波长:", self.nir_upper_wavelength)
|
||||
self.goodman_a = QDoubleSpinBox()
|
||||
self.goodman_a.setDecimals(6)
|
||||
self.goodman_a.setRange(0, 1)
|
||||
@ -88,22 +92,30 @@ class Step3View(BaseView):
|
||||
# Kutser 参数组
|
||||
self.kutser_group = QGroupBox("Kutser方法参数")
|
||||
kutser_layout = QFormLayout()
|
||||
self.oxy_band = QSpinBox()
|
||||
self.oxy_band.setRange(0, 200)
|
||||
self.oxy_band.setValue(38)
|
||||
kutser_layout.addRow("氧吸收波段索引:", self.oxy_band)
|
||||
self.lower_oxy = QSpinBox()
|
||||
self.lower_oxy.setRange(0, 200)
|
||||
self.lower_oxy.setValue(36)
|
||||
kutser_layout.addRow("下氧吸收波段索引:", self.lower_oxy)
|
||||
self.upper_oxy = QSpinBox()
|
||||
self.upper_oxy.setRange(0, 200)
|
||||
self.upper_oxy.setValue(49)
|
||||
kutser_layout.addRow("上氧吸收波段索引:", self.upper_oxy)
|
||||
self.nir_band = QSpinBox()
|
||||
self.nir_band.setRange(0, 200)
|
||||
self.nir_band.setValue(47)
|
||||
kutser_layout.addRow("NIR波段索引:", self.nir_band)
|
||||
self.oxy_wavelength = QDoubleSpinBox()
|
||||
self.oxy_wavelength.setDecimals(2)
|
||||
self.oxy_wavelength.setRange(300.0, 3000.0)
|
||||
self.oxy_wavelength.setValue(760.60)
|
||||
self.oxy_wavelength.setSuffix(" nm")
|
||||
kutser_layout.addRow("氧吸收波长:", self.oxy_wavelength)
|
||||
self.lower_wavelength = QDoubleSpinBox()
|
||||
self.lower_wavelength.setDecimals(2)
|
||||
self.lower_wavelength.setRange(300.0, 3000.0)
|
||||
self.lower_wavelength.setValue(742.39)
|
||||
self.lower_wavelength.setSuffix(" nm")
|
||||
kutser_layout.addRow("左肩波长:", self.lower_wavelength)
|
||||
self.upper_wavelength = QDoubleSpinBox()
|
||||
self.upper_wavelength.setDecimals(2)
|
||||
self.upper_wavelength.setRange(300.0, 3000.0)
|
||||
self.upper_wavelength.setValue(860.48)
|
||||
self.upper_wavelength.setSuffix(" nm")
|
||||
kutser_layout.addRow("右肩波长:", self.upper_wavelength)
|
||||
self.nir_wavelength = QDoubleSpinBox()
|
||||
self.nir_wavelength.setDecimals(2)
|
||||
self.nir_wavelength.setRange(300.0, 3000.0)
|
||||
self.nir_wavelength.setValue(842.36)
|
||||
self.nir_wavelength.setSuffix(" nm")
|
||||
kutser_layout.addRow("NIR参考波长:", self.nir_wavelength)
|
||||
self.kutser_group.setLayout(kutser_layout)
|
||||
self.kutser_group.setVisible(False)
|
||||
layout.addWidget(self.kutser_group)
|
||||
@ -111,10 +123,12 @@ class Step3View(BaseView):
|
||||
# Hedley 参数组
|
||||
self.hedley_group = QGroupBox("Hedley方法参数")
|
||||
hedley_layout = QFormLayout()
|
||||
self.hedley_nir_band = QSpinBox()
|
||||
self.hedley_nir_band.setRange(0, 200)
|
||||
self.hedley_nir_band.setValue(47)
|
||||
hedley_layout.addRow("NIR波段索引:", self.hedley_nir_band)
|
||||
self.hedley_nir_wavelength = QDoubleSpinBox()
|
||||
self.hedley_nir_wavelength.setDecimals(2)
|
||||
self.hedley_nir_wavelength.setRange(300.0, 3000.0)
|
||||
self.hedley_nir_wavelength.setValue(842.36)
|
||||
self.hedley_nir_wavelength.setSuffix(" nm")
|
||||
hedley_layout.addRow("NIR参考波长:", self.hedley_nir_wavelength)
|
||||
self.hedley_group.setLayout(hedley_layout)
|
||||
self.hedley_group.setVisible(False)
|
||||
layout.addWidget(self.hedley_group)
|
||||
@ -210,17 +224,17 @@ class Step3View(BaseView):
|
||||
|
||||
method = self.method.currentData()
|
||||
if method == "goodman":
|
||||
config["nir_lower"] = self.nir_lower.value()
|
||||
config["nir_upper"] = self.nir_upper.value()
|
||||
config["nir_lower_wavelength"] = self.nir_lower_wavelength.value()
|
||||
config["nir_upper_wavelength"] = self.nir_upper_wavelength.value()
|
||||
config["goodman_A"] = self.goodman_a.value()
|
||||
config["goodman_B"] = self.goodman_b.value()
|
||||
elif method == "kutser":
|
||||
config["oxy_band"] = self.oxy_band.value()
|
||||
config["lower_oxy"] = self.lower_oxy.value()
|
||||
config["upper_oxy"] = self.upper_oxy.value()
|
||||
config["nir_band"] = self.nir_band.value()
|
||||
config["oxy_wavelength"] = self.oxy_wavelength.value()
|
||||
config["lower_wavelength"] = self.lower_wavelength.value()
|
||||
config["upper_wavelength"] = self.upper_wavelength.value()
|
||||
config["nir_wavelength"] = self.nir_wavelength.value()
|
||||
elif method == "hedley":
|
||||
config["hedley_nir_band"] = self.hedley_nir_band.value()
|
||||
config["hedley_nir_wavelength"] = self.hedley_nir_wavelength.value()
|
||||
elif method == "sugar":
|
||||
config["sugar_iter"] = self.sugar_iter.value()
|
||||
config["sugar_sigma"] = self.sugar_sigma.value()
|
||||
|
||||
Reference in New Issue
Block a user