进行路径计算
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
"""
|
||||
计算所有隐患点的灾害影响范围并填充 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()
|
||||
Reference in New Issue
Block a user