自驾路书规划师 (Road Trip Planner)
Overview
把几个行程参数变成一份可复用的路书,交付两种互补形态:
- 图文路书 — 可打印 / 手机滑读的每日旅行手册(HTML 优先,需 docx/pdf 时用
workbuddy-docx技能转换)。 - 交互地图 HTML — 带路线折线与逐点可点击弹窗的地图(由
scripts/build_map.py生成)。
硬性差异点(用户明确要求,不可妥协)已编码在 references/roadbook-spec.md:
- 🍜 美食必须当地认可 — 百年老店 / 老字号 / 非遗 / 本地人高频光顾;主动剔除靠短视频爆火、以排队打卡为卖点的网红店。
- 🎫 门票逐条列清 — 成人 / 儿童(标免票身高线)/ 老人(标年龄线)。
- 💰 平台比价 — 抖音 / 美团 / 大众点评套餐 vs 直接点餐,给出明确建议。
- ⚡ 能源规划 — ICE:加油站 + 优惠;EV:充电桩 + 续航缓冲 + 高速服务区。
When to Use
- "帮我规划去XX的自驾路书,X天"
- "开车带老人孩子去XX,出一份路书"
- "做个XX到XX的自驾攻略,要地图和文档"
- 任何 自驾 + 行程 + 景点/美食/加油充电/门票 的组合需求。
Workflow
Step 1 — 收参数(缺失必问)
用 AskUserQuestion 问齐:出发地/目的地、天数与日期弹性、油车(ICE)还是电车(EV)、同行人(人数、儿童身高与年龄、老人年龄、特殊需求)、偏好(辣/清淡/清真/忌口、节奏、必去清单、住宿预算、是否接受夜路)。
仅当用户说"你定"才用默认:单日驾驶≤8h、舒适型住宿、偏松弛节奏。
Step 2 — 搭路线骨架
切成每日段落,单日驾驶 ≤8h / ≤500–600km(山路高原 ≤6h)。每段记录 from/to、distance_km、duration_h、主要道路编号、一句话概述。
按 references/research-guide.md 用联网工具核实真实里程与道路。
Step 3 — 逐日调研
填充途经点,type 取 start | attraction | food | fuel | charge | service | hotel | end。
内容规则严格执行 references/roadbook-spec.md(R1–R6),数据获取方法见 references/research-guide.md。
坐标缺失时用 scripts/poi_lookup.py 升级为 POI 级(见 Step 3.5),仍缺则用 scripts/geocode.py。
Step 3.5 — 坐标升级到 POI 级(关键步骤,不可跳过)
用户要「标记点与地图上位置准确对应」,就必须做到 POI 级(店门口,误差 <30m),
而不是街道级/地标级(误差 100~600m)。中文地址库做不到,需要地图 API。
export BDMAP_AK=你的百度Web服务AK
python scripts/poi_lookup.py trip.json --out coords_poi.json
python scripts/merge_coords.py # 合并成 coords_v2.json
- 百度开放平台建 Web服务 应用,开启「地点检索」「地理编码」「驾车路线规划」
- IP 白名单加本机出口 IP(
curl ifconfig.me),选 IP 校验而非数字签名(避开两代签名算法坑) - 地点检索配额仅 100 次/日,脚本自带断点续跑,分批跑
merge_coords.py会把 POI 级坐标反解成 WGS84 + GCJ02 双份,并保留每条的判定理由- 必须人工复核位移 >1km 的条目:POI 检索会匹配到同名的别家店/养车店,
merge_coords.py的输出会列出 TOP 偏移,逐条判断「保留百度 / 退回旧值 / 指定修正」
Step 3.6 — 生成真实路网路线(关键步骤)
手工写的「途经点直线连线」不是能开的路。真实路网要走国道/高速/省道,含真实弯道、路口、立交。
python scripts/route_real.py trip.json --out route_bd.json
python scripts/compact_route.py 12 # Douglas-Peucker 抽稀 → route_compact.json
python scripts/build_day_facts.py # 每日事实表 → day_facts.json
- 抽稀容差 12m(实测偏差 ≤12.05m,点数降到 17%,地图上看不出差别)
day_facts.json给出每日真实里程/耗时/过路费/红绿灯数/实际路名,用它替换手工估算- 段归属日:段 (d0→d1) 的驾驶发生在 d1 那天早上(从 d0 的酒店退房出发)
Step 4 — 写 Trip JSON(唯一事实来源)
schema 见 references/roadbook-spec.md。图与文档都从它渲染,保证不矛盾。
Step 5 — 生成交互地图
python scripts/build_map.py <trip.json> <output.html>
Leaflet + 国内可访问的 Geoq 瓦片(无需 API key),每日分色折线,弹窗含地址/营业时间/门票/比价/补能/提示。生成后打开验证标点加载正常。
有 route_compact.json 时,地图应叠一层「真实路网」:
- 真实路网(粗实线,深色描边)= 导航软件走的实际路径
- 日程连线(细线)= 途经点直线示意
- 顶部加「🛣️ 真实路网」chip 控制显隐;点某天日程时同步高亮当天路段
- 路段 popup 展示:里程 / 纯驾驶 / 过路费 / 红绿灯数 / 主要路名 / 路径点数
Step 6 — 生成图文路书
从同一 JSON 渲染图文版:封面 → 行前须知(车况/能源/天气/安全)→ 每日行程(路线 + 途经点卡片,美食比价表、景点门票表)→ 预算参考 → 附录(装备/紧急电话)。HTML 优先(手机可读),需要 .docx/.pdf 时加载 workbuddy-docx 技能。
Step 7 — 交付
用 present_files 呈现。对话里给 5 行摘要:总里程 / 天数 / 每日驾驶上限是否达标 / 美食老店数量 / 能源补给关键点,并给出可调整项。
云端 / 手机端执行说明(重要)
本技能可能运行在云端沙箱(微信小程序「腾讯 WorkBuddy」→ 云端工作模式)中,此时没有用户本地电脑。执行要点:
- 脚本一律用相对本技能目录的路径调用,例如
python skills/road-trip-planner/scripts/build_map.py trip.json roadbook-map.html;
先用ls skills/road-trip-planner/确认实际位置,不要假设绝对路径。 - 沙箱内
python可能为python3或python,两者都试一次。 - 云端没有本地
~/.workbuddy/skills目录,本技能目录就是唯一入口。 - 云端联网检索可用,门票/充电桩/里程仍必须检索真实数据,查不到就标"待核实"。
- 交付物必须是单文件(地图 HTML 全部内联,图片用外链或占位),方便在手机浏览器直接打开或转发微信。
- 输出路径统一放在当前工作目录,文件名用中文短名(便于手机端识别下载)。
Resources
references/
roadbook-spec.md— 强制内容规则 + JSON schema,Step 3 前必读。research-guide.md— 各类数据(路线/门票/美食甄别/能源/天气)如何用联网工具查真实数据。real-route-api.md— 真实路网 + POI 级坐标实战参考(百度 API 配额/错误码/坐标顺序陷阱/
响应结构/坐标转换/端点吸附/抽稀容差/合并复核),Step 3.5 前必读。
scripts/
bdmap.py— 百度地图 Web 服务客户端(POI 检索/地理编码/驾车路径规划 + BD09↔GCJ02↔WGS84 转换)。poi_lookup.py— 店名/地址 → POI 级精确坐标(断点续跑,注意 100 次/日配额)。merge_coords.py— 多来源坐标库合并 + 偏移复核报告(人工判定保留哪一套)。route_real.py— trip.json → 真实路网驾车路线(result.routes[0].steps[].path)。compact_route.py— 折线抽稀(Douglas-Peucker,容差 12m)+ 扁平化,供地图内联。build_day_facts.py— 真实路网 → 每日事实表(里程/耗时/过路费/路名),供文档使用。build_map.py— JSON → 交互 HTML 地图(Leaflet + Geoq 瓦片)。geocode.py— 地名列表 → 坐标(Nominatim 兜底,国内常被墙;优先用 poi_lookup.py)。
sample-trip.json
- 示例数据结构参考(2 日演示)。