|
@@ -12,7 +12,7 @@ import shutil
|
|
import sys
|
|
import sys
|
|
|
|
|
|
# 导入MappingUtils
|
|
# 导入MappingUtils
|
|
-from ..utils.mapping_utils import MappingUtils, csv_to_raster_workflow
|
|
|
|
|
|
+from ..utils.mapping_utils import MappingUtils, csv_to_raster_workflow, dataframe_to_raster_workflow
|
|
# 导入土地利用服务
|
|
# 导入土地利用服务
|
|
from .land_use_service import land_use_service
|
|
from .land_use_service import land_use_service
|
|
# 导入边界服务
|
|
# 导入边界服务
|
|
@@ -90,7 +90,7 @@ def get_boundary_gdf_from_database(area: str, level: str) -> Optional[gpd.GeoDat
|
|
|
|
|
|
|
|
|
|
# 土地数据处理函数
|
|
# 土地数据处理函数
|
|
-def process_land_data(land_type, coefficient_params=None):
|
|
|
|
|
|
+def process_land_data(land_type, coefficient_params=None, save_csv=True):
|
|
"""处理土地类型数据并生成清洗后的简化数据"""
|
|
"""处理土地类型数据并生成清洗后的简化数据"""
|
|
base_dir = get_base_dir()
|
|
base_dir = get_base_dir()
|
|
xls_file = os.path.join(base_dir, "..", "static", "water", "Data", "Irrigation_water_SamplingPoint.xlsx")
|
|
xls_file = os.path.join(base_dir, "..", "static", "water", "Data", "Irrigation_water_SamplingPoint.xlsx")
|
|
@@ -104,14 +104,14 @@ def process_land_data(land_type, coefficient_params=None):
|
|
|
|
|
|
if land_centers_df is None or land_centers_df.empty:
|
|
if land_centers_df is None or land_centers_df.empty:
|
|
logger.warning(f"数据库中没有找到 '{land_type}' 类型的土地利用数据")
|
|
logger.warning(f"数据库中没有找到 '{land_type}' 类型的土地利用数据")
|
|
- return None, None
|
|
|
|
|
|
+ return None, None, None
|
|
|
|
|
|
logger.info(f"从数据库获取到 {len(land_centers_df)} 个 '{land_type}' 类型的土地数据")
|
|
logger.info(f"从数据库获取到 {len(land_centers_df)} 个 '{land_type}' 类型的土地数据")
|
|
|
|
|
|
# 读取Excel采样点数据
|
|
# 读取Excel采样点数据
|
|
if not os.path.exists(xls_file):
|
|
if not os.path.exists(xls_file):
|
|
logger.error(f"采样点Excel文件不存在: {xls_file}")
|
|
logger.error(f"采样点Excel文件不存在: {xls_file}")
|
|
- return None, None
|
|
|
|
|
|
+ return None, None, None
|
|
|
|
|
|
df_xls = pd.read_excel(xls_file)
|
|
df_xls = pd.read_excel(xls_file)
|
|
logger.info(f"读取到 {len(df_xls)} 个采样点数据")
|
|
logger.info(f"读取到 {len(df_xls)} 个采样点数据")
|
|
@@ -149,11 +149,6 @@ def process_land_data(land_type, coefficient_params=None):
|
|
cd_value = nearest['Cd (ug/L)'] * Num
|
|
cd_value = nearest['Cd (ug/L)'] * Num
|
|
cd_values.append(cd_value)
|
|
cd_values.append(cd_value)
|
|
|
|
|
|
- # 创建输出目录
|
|
|
|
- data_dir = os.path.join(base_dir, "..", "static", "water", "Data")
|
|
|
|
- os.makedirs(data_dir, exist_ok=True)
|
|
|
|
- logger.info(f"数据目录: {data_dir}")
|
|
|
|
-
|
|
|
|
# 创建简化数据DataFrame
|
|
# 创建简化数据DataFrame
|
|
simplified_data = pd.DataFrame({
|
|
simplified_data = pd.DataFrame({
|
|
'lon': [c[0] for c in centers],
|
|
'lon': [c[0] for c in centers],
|
|
@@ -184,12 +179,21 @@ def process_land_data(land_type, coefficient_params=None):
|
|
]
|
|
]
|
|
logger.info(f"清洗后数据点数: {len(cleaned_data)}")
|
|
logger.info(f"清洗后数据点数: {len(cleaned_data)}")
|
|
|
|
|
|
- # 保存清洗后的简化数据CSV
|
|
|
|
- cleaned_csv = os.path.join(data_dir, f"中心点经纬度与预测值&{land_type}_清洗.csv")
|
|
|
|
- cleaned_data.to_csv(cleaned_csv, index=False, encoding='utf-8-sig')
|
|
|
|
- logger.info(f"保存CSV: {cleaned_csv}")
|
|
|
|
|
|
+ # 可选:保存CSV文件用于兼容性和调试
|
|
|
|
+ cleaned_csv_path = None
|
|
|
|
+ if save_csv:
|
|
|
|
+ # 创建输出目录
|
|
|
|
+ data_dir = os.path.join(base_dir, "..", "static", "water", "Data")
|
|
|
|
+ os.makedirs(data_dir, exist_ok=True)
|
|
|
|
+ logger.info(f"数据目录: {data_dir}")
|
|
|
|
+
|
|
|
|
+ cleaned_csv_path = os.path.join(data_dir, f"中心点经纬度与预测值&{land_type}_清洗.csv")
|
|
|
|
+ cleaned_data.to_csv(cleaned_csv_path, index=False, encoding='utf-8-sig')
|
|
|
|
+ logger.info(f"保存CSV: {cleaned_csv_path}")
|
|
|
|
+ else:
|
|
|
|
+ logger.info("跳过CSV文件生成(内存处理优化)")
|
|
|
|
|
|
- return cleaned_csv, Num
|
|
|
|
|
|
+ return cleaned_data, Num, cleaned_csv_path # 返回DataFrame, 系数, 和CSV路径(如果生成了)
|
|
|
|
|
|
|
|
|
|
# 可视化函数(完全使用统一的MappingUtils接口)
|
|
# 可视化函数(完全使用统一的MappingUtils接口)
|
|
@@ -285,7 +289,6 @@ def plot_tif_histogram(file_path, output_path, figsize=(8, 8),
|
|
return None
|
|
return None
|
|
|
|
|
|
|
|
|
|
-# 完整的处理流程(已更新为完全使用统一绘图接口,支持动态边界和插值控制)
|
|
|
|
def process_land_to_visualization(land_type, coefficient_params=None,
|
|
def process_land_to_visualization(land_type, coefficient_params=None,
|
|
color_map_name="绿-黄-红-紫",
|
|
color_map_name="绿-黄-红-紫",
|
|
output_size=8,
|
|
output_size=8,
|
|
@@ -293,7 +296,8 @@ def process_land_to_visualization(land_type, coefficient_params=None,
|
|
level: Optional[str] = None,
|
|
level: Optional[str] = None,
|
|
enable_interpolation: Optional[bool] = True,
|
|
enable_interpolation: Optional[bool] = True,
|
|
interpolation_method: Optional[str] = "linear",
|
|
interpolation_method: Optional[str] = "linear",
|
|
- resolution_factor: Optional[float] = 4.0):
|
|
|
|
|
|
+ resolution_factor: Optional[float] = 4.0,
|
|
|
|
+ save_csv: Optional[bool] = True):
|
|
"""
|
|
"""
|
|
完整的土地数据处理可视化流程(使用统一的MappingUtils接口,支持动态边界和插值控制)
|
|
完整的土地数据处理可视化流程(使用统一的MappingUtils接口,支持动态边界和插值控制)
|
|
|
|
|
|
@@ -316,14 +320,19 @@ def process_land_to_visualization(land_type, coefficient_params=None,
|
|
@param enable_interpolation: 是否启用空间插值,默认True
|
|
@param enable_interpolation: 是否启用空间插值,默认True
|
|
@param interpolation_method: 插值方法,nearest | linear | cubic,默认linear
|
|
@param interpolation_method: 插值方法,nearest | linear | cubic,默认linear
|
|
@param resolution_factor: 分辨率因子,默认4.0,越大分辨率越高
|
|
@param resolution_factor: 分辨率因子,默认4.0,越大分辨率越高
|
|
|
|
+ @param save_csv: 是否生成CSV文件,默认True
|
|
@returns: 包含所有生成文件路径的元组
|
|
@returns: 包含所有生成文件路径的元组
|
|
"""
|
|
"""
|
|
base_dir = get_base_dir()
|
|
base_dir = get_base_dir()
|
|
logger.info(f"开始处理: {land_type}")
|
|
logger.info(f"开始处理: {land_type}")
|
|
|
|
|
|
- # 1. 生成清洗后的CSV
|
|
|
|
- cleaned_csv, used_coeff = process_land_data(land_type, coefficient_params)
|
|
|
|
- if not cleaned_csv:
|
|
|
|
|
|
+ # 1. 生成清洗后的数据(内存处理,可选择是否保存CSV)
|
|
|
|
+ cleaned_data, used_coeff, cleaned_csv_path = process_land_data(
|
|
|
|
+ land_type,
|
|
|
|
+ coefficient_params,
|
|
|
|
+ save_csv=save_csv # 根据参数决定是否生成CSV文件
|
|
|
|
+ )
|
|
|
|
+ if cleaned_data is None:
|
|
logger.error(f"处理土地数据失败: {land_type}")
|
|
logger.error(f"处理土地数据失败: {land_type}")
|
|
return None, None, None, None, None, None
|
|
return None, None, None, None, None, None
|
|
|
|
|
|
@@ -346,24 +355,23 @@ def process_land_to_visualization(land_type, coefficient_params=None,
|
|
else:
|
|
else:
|
|
logger.info("未能获取默认边界,栅格转换将使用数据点范围")
|
|
logger.info("未能获取默认边界,栅格转换将使用数据点范围")
|
|
|
|
|
|
- # 3. 使用csv_to_raster_workflow转换为GeoTIFF(支持动态边界)
|
|
|
|
|
|
+ # 3. 使用dataframe_to_raster_workflow转换为GeoTIFF(内存处理,支持动态边界)
|
|
raster_dir = os.path.join(base_dir, "..", "static", "water", "Raster")
|
|
raster_dir = os.path.join(base_dir, "..", "static", "water", "Raster")
|
|
template_tif = os.path.join(raster_dir, "meanTemp.tif")
|
|
template_tif = os.path.join(raster_dir, "meanTemp.tif")
|
|
- output_dir = os.path.dirname(cleaned_csv) # 使用CSV所在目录作为输出目录
|
|
|
|
|
|
+ output_dir = raster_dir # 直接使用raster目录作为输出目录
|
|
|
|
|
|
- # 调用csv_to_raster_workflow,支持动态边界和插值控制
|
|
|
|
- workflow_result = csv_to_raster_workflow(
|
|
|
|
- csv_file=cleaned_csv,
|
|
|
|
|
|
+ # 调用dataframe_to_raster_workflow,支持动态边界和插值控制(内存处理优化)
|
|
|
|
+ workflow_result = dataframe_to_raster_workflow(
|
|
|
|
+ df=cleaned_data, # 直接使用DataFrame
|
|
template_tif=template_tif,
|
|
template_tif=template_tif,
|
|
output_dir=output_dir,
|
|
output_dir=output_dir,
|
|
- boundary_shp=None, # 不使用Shapefile
|
|
|
|
boundary_gdf=boundary_gdf, # 直接使用GeoDataFrame
|
|
boundary_gdf=boundary_gdf, # 直接使用GeoDataFrame
|
|
resolution_factor=resolution_factor, # 可配置的分辨率因子
|
|
resolution_factor=resolution_factor, # 可配置的分辨率因子
|
|
interpolation_method=interpolation_method, # 可配置的插值方法
|
|
interpolation_method=interpolation_method, # 可配置的插值方法
|
|
field_name='Prediction',
|
|
field_name='Prediction',
|
|
- lon_col=0, # CSV中经度列索引
|
|
|
|
- lat_col=1, # CSV中纬度列索引
|
|
|
|
- value_col=2, # CSV中数值列索引
|
|
|
|
|
|
+ lon_col=0, # DataFrame中经度列索引
|
|
|
|
+ lat_col=1, # DataFrame中纬度列索引
|
|
|
|
+ value_col=2, # DataFrame中数值列索引
|
|
enable_interpolation=enable_interpolation # 可配置的插值开关
|
|
enable_interpolation=enable_interpolation # 可配置的插值开关
|
|
)
|
|
)
|
|
|
|
|
|
@@ -425,6 +433,14 @@ def process_land_to_visualization(land_type, coefficient_params=None,
|
|
except Exception as e:
|
|
except Exception as e:
|
|
logger.error(f"直方图生成失败: {str(e)}")
|
|
logger.error(f"直方图生成失败: {str(e)}")
|
|
|
|
|
|
|
|
+ # 使用实际的CSV路径(如果生成了)或生成兼容性路径
|
|
|
|
+ if cleaned_csv_path:
|
|
|
|
+ cleaned_csv = cleaned_csv_path
|
|
|
|
+ else:
|
|
|
|
+ # 为了兼容性,生成路径(即使文件不存在)
|
|
|
|
+ data_dir = os.path.join(base_dir, "..", "static", "water", "Data")
|
|
|
|
+ cleaned_csv = os.path.join(data_dir, f"中心点经纬度与预测值&{land_type}_清洗.csv")
|
|
|
|
+
|
|
return cleaned_csv, workflow_result['shapefile'], output_tif, map_output, hist_output, used_coeff
|
|
return cleaned_csv, workflow_result['shapefile'], output_tif, map_output, hist_output, used_coeff
|
|
|
|
|
|
|
|
|