"""
案例 4数据准备：××市低空巡检遥感监测时序数据集（模拟）

培训说明：
本脚本生成的是结构与真实业务一致的模拟数据，用于演示分析流程。
真实培训中应替换为客户脱敏后的实际数据。

数据结构参照低空政务巡检的典型输出：
- 每日多架次无人机巡检，覆盖若干网格
- 每架次产出影像，经AI 算法识别出违建/裸土/垃圾堆放/水体异色等问题
- 附带气象条件（影响飞行与成像质量）
"""
import numpy as np
import pandas as pd

rng = np.random.default_rng(20260809)

# ---------- 基础设定 ----------
dates = pd.date_range("2026-05-01", "2026-08-08", freq="D")
grids = [f"G{i:02d}" for i in range(1, 25)]          # 24 个巡检网格
grid_type = {}
for i, g in enumerate(grids):
    if i < 6:
        grid_type[g] = "城中村"
    elif i < 12:
        grid_type[g] = "工业园区"
    elif i < 18:
        grid_type[g] = "城乡结合部"
    else:
        grid_type[g] = "水域岸线"

problem_types = ["违法建设", "裸土未覆盖", "垃圾堆放", "水体异色", "秸秆焚烧"]

# 不同网格类型的问题基线发生率
base_rate = {
    "城中村":     {"违法建设": 2.4, "裸土未覆盖": 0.6, "垃圾堆放": 1.8, "水体异色": 0.1, "秸秆焚烧": 0.05},
    "工业园区":   {"违法建设": 0.9, "裸土未覆盖": 1.9, "垃圾堆放": 1.1, "水体异色": 0.5, "秸秆焚烧": 0.1},
    "城乡结合部": {"违法建设": 1.6, "裸土未覆盖": 2.2, "垃圾堆放": 1.4, "水体异色": 0.2, "秸秆焚烧": 0.9},
    "水域岸线":   {"违法建设": 0.4, "裸土未覆盖": 0.5, "垃圾堆放": 0.9, "水体异色": 1.7, "秸秆焚烧": 0.2},
}

records = []
sortie_id = 0

for d in dates:
    doy = d.dayofyear
    # 气象：风速与能见度有季节与随机波动
    wind = float(np.clip(rng.normal(3.6+ 1.2 * np.sin(doy / 22), 1.5), 0.2, 14))
    vis = float(np.clip(rng.normal(13- 3 * np.sin(doy / 30), 4), 0.8, 30))
    rain = float(max(0, rng.gamma(0.6, 4) - 2.2))

    # 恶劣天气停飞：风速 >10 m/s 或 能见度<3 km 或 降水 >8 mm
    grounded = (wind > 10) or (vis < 3) or (rain > 8)

    # 每日巡检网格数（停飞则为 0）
    n_grid = 0 if grounded else int(rng.integers(8, 15))
    today_grids = rng.choice(grids, size=n_grid, replace=False) if n_grid else []

    for g in today_grids:
        sortie_id += 1
        gt = grid_type[g]
        # 成像质量受能见度影响
        img_quality = float(np.clip(rng.normal(0.92 - max(0, (8 - vis)) * 0.035, 0.05), 0.35, 0.995))
        flight_min = float(np.clip(rng.normal(28, 7), 12, 55))
        area = float(np.clip(rng.normal(2.6, 0.7), 0.8, 5.2))

        for pt in problem_types:
            lam = base_rate[gt][pt] * (area / 2.6)
            # 6 月起加强执法，违法建设与垃圾堆放呈下降趋势
            if d >= pd.Timestamp("2026-06-15") and pt in ("违法建设", "垃圾堆放"):
                lam *= 0.62
            # 秸秆焚烧在 6 月上旬麦收季陡增
            if pt == "秸秆焚烧" and pd.Timestamp("2026-06-01") <= d <= pd.Timestamp("2026-06-12"):
                lam *= 7.5
            # 成像质量低会漏检
            lam *= img_quality

            n = int(rng.poisson(lam))
            if n == 0:
                continue
            for _ in range(n):
                conf = float(np.clip(rng.beta(6, 2) * img_quality + 0.05, 0.3, 0.995))
                records.append({
                    "date": d.date().isoformat(),
                    "sortie_id": f"S{sortie_id:05d}",
                    "grid_id": g,
                    "grid_type": gt,
                    "problem_type": pt,
                    "confidence": round(conf, 3),
                    "area_km2": round(area, 2),
                    "flight_minutes": round(flight_min, 1),
                    "wind_ms": round(wind, 2),
                    "visibility_km": round(vis, 1),
                    "rain_mm": round(rain, 1),
                    "img_quality": round(img_quality, 3),
                    "verified": bool(rng.random() < (0.55 + 0.4 * conf)),
                })

df = pd.DataFrame(records)
df.to_csv("/Users/frank/WorkBuddy/2026-08-09-23-27-38/geovis-training/data/低空巡检监测数据.csv",
          index=False, encoding="utf-8-sig")

# 单独存一份每日飞行日志（含停飞日）
log = []
for d in dates:
    sub = df[df["date"] == d.date().isoformat()]
    if len(sub):
        log.append({
            "date": d.date().isoformat(),
            "sorties": sub["sortie_id"].nunique(),
            "grids": sub["grid_id"].nunique(),
            "problems": len(sub),
            "wind_ms": sub["wind_ms"].iloc[0],
            "visibility_km": sub["visibility_km"].iloc[0],
            "rain_mm": sub["rain_mm"].iloc[0],
            "grounded": 0,
        })
    else:
        log.append({"date": d.date().isoformat(), "sorties": 0, "grids": 0, "problems": 0,
                    "wind_ms": None, "visibility_km": None, "rain_mm": None, "grounded": 1})
pd.DataFrame(log).to_csv(
    "/Users/frank/WorkBuddy/2026-08-09-23-27-38/geovis-training/data/巡检飞行日志.csv",
    index=False, encoding="utf-8-sig")

print(f"记录数: {len(df)}")
print(f"日期范围: {df['date'].min()} ~ {df['date'].max()}")
print(f"网格数: {df['grid_id'].nunique()}  架次数: {df['sortie_id'].nunique()}")
print(f"停飞天数: {sum(1 for r in log if r['grounded'])} / {len(dates)}")
print(df.head(3).to_string())
