Files
wow/route_profile.py
2026-05-12 17:09:19 +08:00

104 lines
3.3 KiB
Python

import json
import os
def normalize_points(raw_points):
"""Return route points as [(x, y), ...], dropping malformed entries."""
points = []
if not isinstance(raw_points, list):
return points
for point in raw_points:
if not isinstance(point, (list, tuple)) or len(point) < 2:
continue
try:
points.append((float(point[0]), float(point[1])))
except (TypeError, ValueError):
continue
return points
def _looks_like_points(raw_value):
if not isinstance(raw_value, list) or not raw_value:
return False
first = raw_value[0]
if not isinstance(first, (list, tuple)) or len(first) < 2:
return False
try:
float(first[0])
float(first[1])
except (TypeError, ValueError):
return False
return True
def normalize_route(raw_route, fallback_name=""):
"""Normalize {"name": ..., "points": ...} into a route dict."""
if raw_route is None:
return None
if isinstance(raw_route, dict):
name = str(raw_route.get("name") or fallback_name or "未命名路线").strip()
raw_points = (
raw_route.get("points")
or raw_route.get("waypoints")
or raw_route.get("path")
or []
)
else:
name = str(fallback_name or "未命名路线").strip()
raw_points = raw_route
points = normalize_points(raw_points)
if not points:
return None
return {"name": name or fallback_name or "未命名路线", "points": points}
def normalize_route_list(raw_routes, fallback_prefix):
routes = []
if raw_routes is None:
return routes
if _looks_like_points(raw_routes):
route = normalize_route(raw_routes, fallback_prefix)
return [route] if route else []
if isinstance(raw_routes, dict):
raw_routes = raw_routes.get("routes") or raw_routes.get("items") or []
if not isinstance(raw_routes, list):
return routes
for idx, raw_route in enumerate(raw_routes, start=1):
route = normalize_route(raw_route, f"{fallback_prefix}{idx}")
if route:
routes.append(route)
return routes
def normalize_route_profile(data, fallback_name=""):
if not isinstance(data, dict):
raise ValueError("路线方案 JSON 必须是对象格式")
name = str(data.get("name") or fallback_name or "未命名方案").strip()
patrol_routes = normalize_route_list(data.get("patrol_routes"), "巡逻路线")
if not patrol_routes:
raise ValueError("路线方案必须包含至少一条 patrol_routes")
return {
"name": name or fallback_name or "未命名方案",
"prepare_route": normalize_route(data.get("prepare_route"), "准备路线"),
"patrol_routes": patrol_routes,
"resurrection_routes": normalize_route_list(data.get("resurrection_routes"), "复活路线"),
"vendor_route": normalize_route(data.get("vendor_route"), "修理商路线"),
"mailbox_route": normalize_route(data.get("mailbox_route"), "邮箱路线"),
}
def load_route_profile(path):
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
fallback_name = os.path.splitext(os.path.basename(path))[0]
return normalize_route_profile(data, fallback_name=fallback_name)