This commit is contained in:
2025-11-09 18:23:19 +08:00
parent f9edc3ea13
commit b5c3b17a1d
11 changed files with 766 additions and 39 deletions

85
main.py
View File

@@ -1,49 +1,56 @@
# main.py
import arcpy
import os
import sys
import geopandas as gpd
import rasterio
from exactextract import exact_extract
try:
proj_lib_path = os.path.join(sys.prefix, 'Lib', 'site-packages', 'rasterio', 'proj_data')
os.environ['PROJ_LIB'] = proj_lib_path
except Exception as e:
print(f"Warning: Could not automatically set PROJ_LIB. Please set it manually. Error: {e}")
# 将项目根目录添加到Python路径以便导入自定义模块
# 假设 main.py 在项目根目录
project_root = os.path.dirname(os.path.abspath(__file__))
if project_root not in sys.path:
sys.path.insert(0, project_root)
# 定义文件路径
raster_path = "D:/工作/三普成果编制/出图数据/容县/栅格0925/AB/AB.tif"
vector_path = "D:/测试文件夹/容县耕园林草.shp"
from src import config
from src.utils.logger_setup import logger
from src.analysis.spatial_analyzer import SpatialAnalyzer
from src.reporting.report_generator import ReportGenerator
# 1. 使用 rasterio 读取栅格的坐标参考系统 (CRS)
with rasterio.open(raster_path) as src:
raster_crs = src.crs
def main():
"""
项目主入口函数,负责调度空间分析和报告生成流程。
"""
logger.info("==================================================")
logger.info(" 地理处理与土壤属性分析项目启动 ")
logger.info("==================================================")
# 2. 使用 geopandas 读取矢量文件
gdf = gpd.read_file(vector_path)
# 确保ArcPy环境可用
try:
arcpy.GetInstallInfo()
logger.info(f"ArcPy环境已加载: {arcpy.GetInstallInfo()['ProductName']} {arcpy.GetInstallInfo()['Version']}")
except Exception as e:
logger.critical(f"ArcPy环境未正确配置或加载失败: {str(e)}")
logger.critical("请确保在ArcGIS Pro的Python环境中运行此脚本。")
sys.exit(1)
# 3. 检查并转换矢量数据的 CRS
print(f"原始矢量CRS: {gdf.crs}")
print(f"目标栅格CRS: {raster_crs}")
# 1. 执行空间分析
logger.info("阶段一:开始执行空间分析...")
analyzer = SpatialAnalyzer(config)
analysis_success = analyzer.execute_analysis()
if gdf.crs != raster_crs:
print("CRS不匹配正在转换矢量数据的CRS...")
# 使用 .to_crs() 方法进行转换
gdf = gdf.to_crs(raster_crs)
print("转换完成。")
# 2. 如果分析成功,则生成报告
if analysis_success:
logger.info("阶段二空间分析完成开始生成Excel报告...")
reporter = ReportGenerator(config)
report_success = reporter.generate_report()
if report_success:
logger.info("阶段二Excel报告生成完毕")
else:
logger.error("阶段二Excel报告生成失败。")
else:
logger.error("阶段一:空间分析失败,请检查日志。")
# 4. 现在,将已经对齐了坐标系的 GeoDataFrame 传递给 exact_extract
# 注意:可以直接传递 GeoDataFrame 对象,而不仅仅是文件路径
stats_to_calculate = ['mean', 'sum', 'count', 'min', 'max']
results = exact_extract(raster_path, gdf, stats_to_calculate)
logger.info("==================================================")
logger.info(" 地理处理与土壤属性分析项目结束 ")
logger.info("==================================================")
# 5. 将结果合并回 GeoDataFrame
# exact_extract 在处理 GeoDataFrame 时,会保留原始的行顺序
for stat in stats_to_calculate:
# 从结果列表中提取每个要素的'properties'字典中的统计值
gdf[stat] = [res['properties'][stat] for res in results]
# 打印最终带有统计结果的 GeoDataFrame
print("\n分区统计结果:")
print(gdf.head())
gdf.to_file("ddddl.shp", driver='ESRI Shapefile', encoding='utf-8')
if __name__ == "__main__":
main()