""" 计算所有隐患点的灾害影响范围并填充 xian_hazard_zones 表 仅计算隐患点 (xian_hidden_danger_spots),不计算风险点。 灾害类型包括: 滑坡、泥石流、山洪、内涝、崩塌 """ import sys import os from datetime import datetime # 确保项目根目录在 sys.path 中 _project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) if _project_root not in sys.path: sys.path.insert(0, _project_root) from app.utils.logger import LoggerManager from app.repositories.hazard_repository import hazard_repository from app.models.hazard.hazard_zone_calculator import hazard_zone_calculator _BATCH_SIZE = 200 # 每处理200条输出一次进度 logger = LoggerManager.get_logger("hazard_zones", os.path.join(_project_root, "logs")) def main(): logger.info("=" * 60) logger.info("开始计算隐患点灾害影响范围") logger.info(f"启动时间: {datetime.now().isoformat()}") logger.info("=" * 60) # 1. 获取所有隐患点 spots = hazard_repository.get_all_hidden_danger_spots() total = len(spots) logger.info(f"查询到 {total} 个隐患点") if total == 0: logger.warning("没有隐患点数据,退出") return # 按灾害类型统计 type_counts = {} for s in spots: dt = s['disaster_type'] type_counts[dt] = type_counts.get(dt, 0) + 1 logger.info(f"灾害类型分布: {type_counts}") # 2. 逐点计算 records = [] success_count = 0 skip_count = 0 error_count = 0 for i, spot in enumerate(spots): sid = spot['source_id'] dtype = spot['disaster_type'] dname = spot['disaster_name'] scale = spot.get('scale_grade') try: zone_wkt, path_wkt = hazard_zone_calculator.calculate( source_id=sid, disaster_type=dtype, scale_grade=scale, lon=spot['lon'], lat=spot['lat'], static_factors=spot['static_factors'] ) if zone_wkt: records.append({ 'source_id': sid, 'disaster_type': dtype, 'zone_wkt': zone_wkt, 'path_wkt': path_wkt }) success_count += 1 else: skip_count += 1 logger.debug(f"跳过 [{sid}] {dname}({dtype}): 无法计算影响范围") except Exception as e: error_count += 1 logger.error(f"计算失败 [{sid}] {dname}({dtype}): {e}") # 进度输出 if (i + 1) % _BATCH_SIZE == 0 or (i + 1) == total: logger.info(f"进度: {i + 1}/{total} " f"(成功:{success_count} 跳过:{skip_count} 失败:{error_count})") # 3. 写入数据库 logger.info(f"计算完成。开始写入数据库,共 {len(records)} 条记录") # 先逻辑删除旧数据 deleted = hazard_repository.delete_existing_zones() logger.info(f"已标记 {deleted} 条旧记录为删除") # 批量写入新数据 inserted = hazard_repository.batch_insert_zones(records) logger.info(f"成功写入 {inserted} 条新记录") # 4. 汇总 logger.info("=" * 60) logger.info("执行完成") logger.info(f" 隐患点总数: {total}") logger.info(f" 计算成功: {success_count}") logger.info(f" 跳过: {skip_count}") logger.info(f" 计算失败: {error_count}") logger.info(f" 写入记录: {inserted}") logger.info(f"完成时间: {datetime.now().isoformat()}") logger.info("=" * 60) if __name__ == '__main__': main()