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:
@ -40,10 +40,15 @@ def _process_one_map(csv_path: str, base_kwargs: dict, output_dir: str
|
||||
if shared_context is not None:
|
||||
# ★ 快速通道:直接调 ContentMapper,复用预计算的网格/掩膜
|
||||
from src.postprocessing.map import ContentMapper
|
||||
mapper = ContentMapper(
|
||||
input_crs=base_kwargs.get('input_crs', 'EPSG:32651'),
|
||||
output_crs=base_kwargs.get('output_crs', base_kwargs.get('input_crs', 'EPSG:32651')),
|
||||
)
|
||||
# ★ CRS 动态探测:从边界文件自动获取,不再硬编码 EPSG:32651
|
||||
input_crs = base_kwargs.get('input_crs') or None
|
||||
output_crs = base_kwargs.get('output_crs') or None
|
||||
boundary_path = base_kwargs.get('boundary_shp_path')
|
||||
mapper = ContentMapper(input_crs=input_crs, output_crs=output_crs)
|
||||
if boundary_path:
|
||||
mapper._ensure_crs(reference_file=str(boundary_path))
|
||||
else:
|
||||
mapper._ensure_crs()
|
||||
result_path = mapper.process_data(
|
||||
csv_file=csv_path,
|
||||
shp_file=base_kwargs.get('boundary_shp_path'),
|
||||
@ -103,7 +108,8 @@ def _pre_vectorize_boundary(boundary_path: str, work_dir: str) -> str:
|
||||
if proj:
|
||||
srs.ImportFromWkt(proj)
|
||||
else:
|
||||
srs.ImportFromEPSG(32651)
|
||||
# 栅格无投影信息时,兜底 WGS84(而非某个特定 UTM 分区)
|
||||
srs.ImportFromEPSG(4326)
|
||||
|
||||
layer = out_ds.CreateLayer('boundary', srs, ogr.wkbMultiPolygon)
|
||||
gdal.Polygonize(band, band, layer, 0, [], callback=None)
|
||||
@ -163,8 +169,8 @@ class Step11MapHandler(BaseStepHandler):
|
||||
base_kwargs = {
|
||||
'boundary_shp_path': resolved_boundary or None,
|
||||
'resolution': float(config.get('resolution', 10.0)),
|
||||
'input_crs': config.get('input_crs', 'EPSG:32651'),
|
||||
'output_crs': config.get('output_crs', config.get('input_crs', 'EPSG:32651')),
|
||||
'input_crs': config.get('input_crs') or None,
|
||||
'output_crs': config.get('output_crs') or None,
|
||||
'show_sample_points': bool(config.get('show_sample_points', False)),
|
||||
'use_distance_diffusion': bool(config.get('use_distance_diffusion', False)),
|
||||
}
|
||||
|
||||
@ -71,11 +71,8 @@ class Step12KrigingHandler(BaseStepHandler):
|
||||
boundary_shp_path=boundary_shp_path,
|
||||
output_image_path=output_image_path,
|
||||
resolution=config.get('resolution', 30),
|
||||
input_crs=config.get('input_crs', 'EPSG:32651'),
|
||||
# ★★★ 强制 output_crs = input_crs,避免 ContentMapper 把栅格重投影到 EPSG:4326 ★★★
|
||||
# 旧实现:output_crs=config.get('output_crs', 'EPSG:4326')
|
||||
# 重投影会让栅格和基于投影坐标的掩膜在 visualize_raster 叠加时发生仿射变换撕裂
|
||||
output_crs=config.get('input_crs', 'EPSG:32651'),
|
||||
input_crs=config.get('input_crs') or None,
|
||||
output_crs=config.get('output_crs') or None,
|
||||
show_sample_points=config.get('show_sample_points', False),
|
||||
base_map_tif=config.get('base_map_tif'),
|
||||
use_distance_diffusion=config.get('use_distance_diffusion', True),
|
||||
|
||||
@ -45,16 +45,16 @@ class Step3GlintRemovalHandler(BaseStepHandler):
|
||||
interpolation_method=config.get('interpolation_method', 'nearest'),
|
||||
enabled=config.get('enabled', True),
|
||||
kutser_shp_path=config.get('kutser_shp_path'),
|
||||
oxy_band=config.get('oxy_band', 38),
|
||||
lower_oxy=config.get('lower_oxy', 36),
|
||||
upper_oxy=config.get('upper_oxy', 49),
|
||||
nir_band=config.get('nir_band', 47),
|
||||
nir_lower=config.get('nir_lower', 25),
|
||||
nir_upper=config.get('nir_upper', 37),
|
||||
goodman_A=config.get('goodman_A', 0.000019),
|
||||
goodman_B=config.get('goodman_B', 0.1),
|
||||
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)),
|
||||
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)),
|
||||
hedley_shp_path=config.get('hedley_shp_path'),
|
||||
hedley_nir_band=config.get('hedley_nir_band', 47),
|
||||
hedley_nir_wavelength=float(config.get('hedley_nir_wavelength', 842.36)),
|
||||
sugar_bounds=config.get('sugar_bounds'),
|
||||
sugar_sigma=config.get('sugar_sigma', 1.0),
|
||||
sugar_estimate_background=config.get('sugar_estimate_background', True),
|
||||
|
||||
@ -209,20 +209,20 @@ class GlintRemovalStep:
|
||||
interpolate_zeros: bool = False,
|
||||
interpolation_method: str = "nearest",
|
||||
enabled: bool = True,
|
||||
# Kutser 参数
|
||||
# Kutser 参数(波长驱动:nm → 自动解析波段号)
|
||||
kutser_shp_path: Optional[str] = None,
|
||||
oxy_band: int = 38,
|
||||
lower_oxy: int = 36,
|
||||
upper_oxy: int = 49,
|
||||
nir_band: int = 47,
|
||||
# Goodman 参数
|
||||
nir_lower: int = 25,
|
||||
nir_upper: int = 37,
|
||||
oxy_wavelength: float = 760.6,
|
||||
lower_wavelength: float = 742.39,
|
||||
upper_wavelength: float = 860.48,
|
||||
nir_wavelength: float = 842.36,
|
||||
# Goodman 参数(波长驱动:统一为 ~640nm / ~750nm 物理波长)
|
||||
nir_lower_wavelength: float = 641.93,
|
||||
nir_upper_wavelength: float = 751.49,
|
||||
goodman_A: float = 0.000019,
|
||||
goodman_B: float = 0.1,
|
||||
# Hedley 参数
|
||||
# Hedley 参数(波长驱动)
|
||||
hedley_shp_path: Optional[str] = None,
|
||||
hedley_nir_band: int = 47,
|
||||
hedley_nir_wavelength: float = 842.36,
|
||||
# SUGAR 参数
|
||||
sugar_bounds: Optional[List[tuple]] = None,
|
||||
sugar_sigma: float = 1.0,
|
||||
@ -383,10 +383,10 @@ class GlintRemovalStep:
|
||||
|
||||
# ==================== Kutser ====================
|
||||
if method == "kutser":
|
||||
print(f"使用方法: Kutser (氧吸收波段={oxy_band}, NIR波段={nir_band})")
|
||||
print(f"使用方法: Kutser (波长驱动: oxy={oxy_wavelength}nm, "
|
||||
f"NIR={nir_wavelength}nm)")
|
||||
hardcoded_bsq = str(deglint_dir / "deglint_kutser.bsq")
|
||||
hardcoded_hdr = hardcoded_bsq.replace(".bsq", ".hdr")
|
||||
# 将用户指定的 output_path 标准化为 .bsq 路径
|
||||
if output_path:
|
||||
final_bsq = output_path.replace('.dat', '.bsq').replace('.tif', '.bsq')
|
||||
final_hdr = final_bsq.replace(".bsq", ".hdr")
|
||||
@ -402,10 +402,10 @@ class GlintRemovalStep:
|
||||
kutser = Kutser(
|
||||
img_path,
|
||||
shp_path=None,
|
||||
oxy_band=oxy_band,
|
||||
lower_oxy=lower_oxy,
|
||||
upper_oxy=upper_oxy,
|
||||
NIR_band=nir_band,
|
||||
oxy_wavelength=oxy_wavelength,
|
||||
lower_wavelength=lower_wavelength,
|
||||
upper_wavelength=upper_wavelength,
|
||||
nir_wavelength=nir_wavelength,
|
||||
water_mask=mask_for_algorithm,
|
||||
output_path=hardcoded_bsq,
|
||||
)
|
||||
@ -420,7 +420,9 @@ class GlintRemovalStep:
|
||||
|
||||
# ==================== Goodman ====================
|
||||
elif method == "goodman":
|
||||
print(f"使用方法: Goodman (NIR波段范围: {nir_lower}-{nir_upper})")
|
||||
print(f"使用方法: Goodman (波长驱动: "
|
||||
f"NIR_lower={nir_lower_wavelength}nm, "
|
||||
f"NIR_upper={nir_upper_wavelength}nm)")
|
||||
hardcoded_bsq = str(deglint_dir / "deglint_goodman.bsq")
|
||||
hardcoded_hdr = hardcoded_bsq.replace(".bsq", ".hdr")
|
||||
if output_path:
|
||||
@ -437,8 +439,8 @@ class GlintRemovalStep:
|
||||
|
||||
goodman = Goodman(
|
||||
img_path,
|
||||
NIR_lower=nir_lower,
|
||||
NIR_upper=nir_upper,
|
||||
nir_lower_wavelength=nir_lower_wavelength,
|
||||
nir_upper_wavelength=nir_upper_wavelength,
|
||||
A=goodman_A,
|
||||
B=goodman_B,
|
||||
water_mask=mask_for_algorithm,
|
||||
@ -458,7 +460,7 @@ class GlintRemovalStep:
|
||||
|
||||
# ==================== Hedley ====================
|
||||
elif method == "hedley":
|
||||
print(f"使用方法: Hedley (NIR波段={hedley_nir_band})")
|
||||
print(f"使用方法: Hedley (波长驱动: NIR={hedley_nir_wavelength}nm)")
|
||||
hardcoded_bsq = str(deglint_dir / "deglint_hedley.bsq")
|
||||
hardcoded_hdr = hardcoded_bsq.replace(".bsq", ".hdr")
|
||||
if output_path:
|
||||
@ -476,7 +478,7 @@ class GlintRemovalStep:
|
||||
hedley = Hedley(
|
||||
img_path,
|
||||
shp_path=None,
|
||||
NIR_band=hedley_nir_band,
|
||||
nir_wavelength=hedley_nir_wavelength,
|
||||
water_mask=mask_for_algorithm,
|
||||
output_path=hardcoded_bsq,
|
||||
)
|
||||
|
||||
@ -19,11 +19,9 @@ class MappingStep:
|
||||
boundary_shp_path: Optional[str] = None, # ★★★ Plan C: None = 不依赖水域掩膜 ★★★
|
||||
output_image_path: Optional[str] = None,
|
||||
resolution: float = 30,
|
||||
input_crs: str = "EPSG:32651",
|
||||
# ★★★ 强制默认 output_crs = input_crs,禁止重投影到 EPSG:4326 ★★★
|
||||
# 历史默认值 'EPSG:4326' 会让 ContentMapper 将插值栅格从投影坐标系转到经纬度坐标系,
|
||||
# 与基于 EPSG:32651 的水域掩膜叠加时发生仿射变换撕裂(栅格错位、坐标轴扭曲)。
|
||||
output_crs: str = "EPSG:32651",
|
||||
input_crs: Optional[str] = None,
|
||||
# ★ CRS 动态探测:ContentMapper 自动从掩膜/栅格中读取投影信息
|
||||
output_crs: Optional[str] = None,
|
||||
show_sample_points: bool = False,
|
||||
base_map_tif: Optional[str] = None,
|
||||
use_distance_diffusion: bool = True,
|
||||
|
||||
Reference in New Issue
Block a user