shuishen
3 days ago fbb068ec702338d609c1ca6eddbdb9f182d8f211
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""Create small, georeferenced validation cases for the risk-rule Demo."""
 
from __future__ import annotations
 
import argparse
import json
from pathlib import Path
 
import geopandas as gpd
from shapely.geometry import Point, box
 
 
CRS = "EPSG:3857"
 
 
def rules_payload() -> dict:
    return {
        "schema_version": 1,
        "score_cap": 100,
        "levels": {"medium": 30, "high": 60, "critical": 85},
        "rules": [
            {"id": "restricted_zone", "type": "zone_intersection", "zone_type": "restricted", "score": 65, "suggestion": "暂停自动处置,复核限制区边界和对象位置。"},
            {"id": "caution_zone", "type": "zone_intersection", "zone_type": "caution", "score": 25, "suggestion": "安排人工复核并确认现场作业条件。"},
            {"id": "low_confidence", "type": "attribute_threshold", "field": "confidence", "operator": "lt", "value": 0.6, "score": 20, "suggestion": "补充观测证据,不以低置信度对象单独定性。"},
        ],
    }
 
 
def write_case(root: Path, name: str, records: list[dict]) -> None:
    directory = root / name
    directory.mkdir(parents=True, exist_ok=False)
    zones = gpd.GeoDataFrame(
        [
            {"zone_id": "caution-a", "zone_type": "caution", "geometry": box(0, 0, 600, 600)},
            {"zone_id": "restricted-a", "zone_type": "restricted", "geometry": box(200, 200, 400, 400)},
        ],
        crs=CRS,
    )
    gpd.GeoDataFrame(records, crs=CRS).to_file(directory / "observations.geojson", driver="GeoJSON")
    zones.to_file(directory / "zones.geojson", driver="GeoJSON")
    (directory / "rules.json").write_text(json.dumps(rules_payload(), ensure_ascii=False, indent=2), encoding="utf-8")
 
 
def write_validation_inputs(output: Path) -> None:
    if output.exists() and any(output.iterdir()):
        raise ValueError(f"Validation output is not empty: {output}")
    output.mkdir(parents=True, exist_ok=True)
    write_case(output, "normal", [
        {"object_id": "normal-outside", "confidence": 0.92, "geometry": Point(750, 750)},
        {"object_id": "normal-caution", "confidence": 0.88, "geometry": Point(120, 120)},
        {"object_id": "normal-restricted", "confidence": 0.85, "geometry": Point(300, 300)},
    ])
    write_case(output, "difficult", [
        {"object_id": "boundary-overlap", "confidence": 0.82, "geometry": Point(200, 300)},
        {"object_id": "low-confidence-restricted", "confidence": 0.45, "geometry": Point(300, 300)},
        {"object_id": "low-confidence-outside", "confidence": 0.50, "geometry": Point(780, 720)},
    ])
 
 
def main() -> int:
    parser = argparse.ArgumentParser(description="Create risk-rule validation GeoJSON and rules.")
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    write_validation_inputs(args.output)
    print(args.output)
    return 0
 
 
if __name__ == "__main__":
    raise SystemExit(main())