2026-07-30 风眼「九段线示意插图」问题地图事故复盘
入档:2026-07-30 来源:风眼 · Typhoon Eye(
E:\typhoon-eye)台风路径图里一块自绘的「南海诸岛九段线示意」插图,上线 19 天后被群友肉眼发现走向错误,当日紧急下线 验证状态:⚠️ 首次;其中合规规则属法规 / 平台事实,不需二次验证
事实记录(不可修改区)
- 项目:风眼 · Typhoon Eye,台风实况与分级应急预案单页站。双发布面:GitHub Pages(
mr-salticidae.github.io/typhoon-eye)+ B 站 Toy(YliUzbE5TOqySu4G/ id8980525008896) - 缺陷内容:
assets/toy-runtime.js里用手写经纬度画的一块 SVG 插图,标题「南海诸岛」、角注「九段线示意」,含 9 条断续线段 + 海南岛 / 台湾岛两个多边形 - 引入:2026-07-11
5690b3f(feat: add Toy 30-minute refresh and nine-dash map inset) - 期间迭代(插图被反复维护,但从未被校验内容):
- 2026-07-12
baec80afix: 九段线插图四角动态避让台风路径 - 2026-07-29
19e492ffix: 远洋视图与自适应小地图(改同一文件,插图原样保留) - CI
toy: rebuild package重建发布包 10 次以上,每次都带着错误插图
- 2026-07-12
- 下线:2026-07-30 12:13
45029d2(整体移除,不修坐标) - 在线时长:19 天(07-11 → 07-30)
- 曝光(B 站 Toy 侧,
toy stats --days 90,区间 07-11 ~ 07-29,07-30 当日未结算):PV 1845 / UV 1510- 对照:发布首日 07-10 单日 PV 18591 / UV 16678 —— 在插图引入之前,不计入本次影响面
- GitHub Pages 侧无访问统计,影响面无法量化(全程在线)
- 发现路径:QQ 群友肉眼质疑(「线要把海南岛包在里面」「这张图把整个北部湾都划到线外了」)→ 作者拿去问豆包 → 豆包判定有误 → 作者转报要求修复。不是自己发现的,也不是任何自动化检查发现的
- 修复方式:整体移除自绘插图,没有去修坐标
- 上线状态:
- GitHub Pages:已 curl 核验线上
toy-runtime.js/index.html,绘制代码 0 处 - B 站 Toy:已提交并过审,平台返回
status: published,mtime2026-07-30 12:36:33(提交后约 6 分钟)
- GitHub Pages:已 curl 核验线上
- 未独立复验项(诚实标注):Toy 线上页面 DOM 未能从命令行抓取复验 —— 资源直链 404、外壳页需真实浏览器环境。Toy 侧「已是修复版」的依据是平台状态,不是我抓到的页面内容
- 补记(2026-07-30,不覆盖上一行):上述复验缺口已由作者人工闭合 —— 作者在真实浏览器里打开 Toy 页面确认插图已消失,回复「验证通过」。同日 B 站专栏对外稿也已发布(
opus/1230719988161052674,发布时未在编辑器内改动,库内版即线上终稿)。结论:两个发布面均已确认下线,但 Toy 侧的最终证据是人工目视,不是自动化检查 —— 风控页面挡住了 WebFetch 与 headless 两条路,这类平台的线上复验目前没有可自动化的手段,下次仍需人来看一眼
- 补记(2026-07-30,不覆盖上一行):上述复验缺口已由作者人工闭合 —— 作者在真实浏览器里打开 Toy 页面确认插图已消失,回复「验证通过」。同日 B 站专栏对外稿也已发布(
- 数据来源:
git log、toy stats --days 90 --json、toy mylist --json、headless Chromium DOM 对照自测
一句话
涉及国家法定表达的内容(疆界 / 国界线 / 南海断续线),不存在「自绘一个简化示意版」这个选项 —— 标注「示意」不免责;这次的错误不是坐标偏差,是把海南岛和整个北部湾画到了线外侧,而它还被精心打磨过一轮(四角动态避让),打磨恰恰让它更像「已经审查过的东西」。
错在哪(技术事实)
自北向南绕一圈的 9 段坐标里,前 7 段大致沿菲律宾以西 → 南端 → 越南以东走,最后两段是硬错:
[[110.2, 16.4], [110.7, 17.9]], // 第 8 段
[[111.9, 19.3], [113.1, 20.5]] // 第 9 段
- 这两段把断续线的北端封口,从越南中部海岸一路横拉到海南岛东南方向、珠江口以南。结果是海南岛、整个北部湾、西沙群岛全部落在线的外侧。
- 正确走向:西侧最北一段位于北部湾内(海南岛与越南之间,约 108°E),北部湾与海南岛都在线内侧。
- 标题写「南海诸岛」,插图里一个岛礁都没画(东沙、西沙、中沙、南沙全缺),只有海南岛和台湾岛两个多边形。
- 段数按 9 段绘制,而现行标准地图(2023 年版)是十段线,台湾岛东侧另有一段。
连带发现的真 bug:app.js 的小地图放置算法把插图矩形建模成障碍(sc / scs / overlap / gapTo 及罚分项)。插图撤掉后这套建模变成幻影障碍,会让小地图无理由地避开右上角;插图还是不透明面板,会盖掉 2 个经纬网标注。移除后 12 个标注全部可见。
为什么是「下线」而不是「改坐标」
这是本次最关键的判断,也是最容易做错的一步(第一反应都是「那我把坐标改对」)。
- 涉及国界线与南海断续线的地图,必须依自然资源部标准画法;向社会公开发布通常还需送审取得审图号(高德地图角上那种「GS(2025)3454 号」)。
- 标注「示意」「仅表示空间趋势」不免责。自绘断续线只要走向、段数与标准不符,就是「问题地图」。
- 一个人手写经纬度,不可能达到标准画法的精度要求 —— 改坐标只是把「明显错的问题地图」变成「不明显错的问题地图」,风险性质没变。
- 所以:删掉,并在代码里写下「不要再加回来」的原因,防止后来者(包括未来的自己和 AI)看到空白又补一个回去。
保留的合规做法:v0.6 的小地图底图用 Natural Earth 1:110m Land(public domain),只含陆地轮廓、不含任何国界线,不受影响。要疆界表达时,唯一合规路子是引用自然资源部标准地图服务 https://bzdt.ch.mnr.gov.cn 的官方图并标注审图号。
结果分析:AI 审查者(豆包)判对了,但理由半数是错的
作者是拿豆包的判断来推动修复的,所以必须单独核对它的可信度 —— 不能因为结论对,就把它的理由也当依据。
| 豆包的说法 | 核对结果 |
|---|---|
| 这张图有明显错误,不能当标准地理地图 | ✅ 结论正确 |
| 岛礁位置严重失真、南沙大片缺失 | ✅ 正确(插图确实没画任何岛礁) |
| 左上角区块对应西沙群岛,右上角对应东沙群岛 | ❌ 看错了。那两个多边形是代码里的 HAINAN_INSET 和 TAIWAN_INSET,即海南岛与台湾岛 |
| 我国南海是九段线,标准为 9 条 | ❌ 过时。现行标准地图为十段线(台湾岛东侧另有一段) |
| 海南岛本体不在九段线内部 | ❌ 错。海南岛在断续线内侧,整个北部湾也在线内侧 |
反倒是群友的肉眼判断完全正确(「线要把海南岛包在里面」「整个北部湾都被划到线外了」),而且指出的正是最严重的那处错误。
结论:AI 审查者适合当警报器(它喊「这里有问题」值得立刻去查),不适合当依据(它给的理由要逐条核实,否则会顺着错理由改出新的错)。这次如果照豆包的「标准是 9 条」去改,只会把十段线改成九段线,错得更隐蔽。
方法论沉淀
1. 法定表达不自绘
核心:疆界、国界线、南海断续线这类国家法定表达,只能引用官方标准源,不能自制「简化示意版」;标「示意」不免责。
来源:本次插图从第一行代码起就注定不合规,与坐标准不准无关。
验证状态:⚠️ 首次(但属法规事实,不依赖二次验证)
操作规则:
- 任何要出现中国地图的场合(网站、短片、海报、Remotion 视频、PPT),先问:只需要陆地轮廓 / 海岸线,还是需要疆界表达?
- 只需陆地轮廓 → 可用 Natural Earth 这类 public domain 数据自绘(不含国界线)。
- 需要疆界表达 → 走 https://bzdt.ch.mnr.gov.cn 官方标准地图 + 标注审图号。不要自己写经纬度画线。
- 别把「加个免责声明」当解决方案。
反例 / 边界:纯抽象的、不指向真实地理的图形(如把台风画成一个漩涡符号)不受此约束 —— 约束触发点是「它看起来在表达真实疆界」。
2. 打磨不等于校验(反直觉,已抽独立律档)
核心:对一个对象做精细打磨(避让、动效、响应式适配),不产生任何关于它内容正确性的证据,反而因为「看起来经过了工序」而抬高自己和他人对它的信任。
来源:2026-07-12 专门写了一次 fix: 九段线插图四角动态避让台风路径 —— 收集路径点坐标、四角打分、给底部两角加罚分,是一段挺讲究的布局算法。做完之后,这块插图在心里的可信度不知不觉升了一级,却从没有人问过一句「这 9 条线画对了吗」。19 天里它被维护了 3 次、重新打包 10 次以上。
验证状态:⚠️ 首次
操作规则:
- 给某个模块做第二次打磨前,先补一句自问:这东西的内容本身,被验证过吗?
- 把「内容正确性」和「呈现质量」当两条独立的检查线,不要让后者的进展代表前者。
- 越是「看起来专业」的产出(地图、图表、法条摘要、医疗数据、统计口径),越要单独校验内容源。
反例 / 边界:对内容正确性已有独立验证的模块(如数据来自权威 API 并校验过),打磨就是纯粹的打磨,不受此律约束。
详见 打磨不等于校验律_v1
3. AI 审查者当警报器,不当依据
核心:AI 指出「这里有问题」值得立刻去查(召回率有价值),但它给的理由必须逐条核实 —— 结论对 + 理由错的组合很常见,照错理由改会引出新错。
来源:豆包 5 条论据里 3 条错(见上表),但它的总结论是对的。
验证状态:⚠️ 首次
操作规则:
- 把 AI 的判断当警报,不当结论;警报响了就自己去查一手事实(标准、法规、源码)。
- 逐条核对它的论据,尤其是「数字类」断言(几段线、几年版本、哪个方位)。
- 别把 AI 的措辞直接抄进修复方案或对外说明。
4. 合规类缺陷的正确处置是下线,不是修正
核心:功能 bug 修到对为止;合规缺陷要先问「这件事我有资格自己做吗」 —— 没资格的,修得再准也仍然违规,正确动作是下线 + 换官方源。
来源:第一反应是「把坐标改对」,但改对也仍是问题地图。
验证状态:⚠️ 首次
操作规则:
- 判定为合规问题后,先分类:能力问题(改得对就行) 还是资格问题(自己做就不行)。
- 资格问题 → 立刻下线止血,再找官方源接回来;不要在「修得更准一点」上投工时。
- 下线的同时在代码里留下原因注释,防止空白被后来者(或 AI)补回去。
下次改进
如果重来,最想改哪一步:2026-07-11 写下 NINE_DASH_SEGMENTS 那 9 行坐标的时候,应该先停下来问一句「疆界这种东西,我有资格自己画吗」。这一句能省掉后面 19 天的暴露和一次紧急下线。
行动清单:
- 立项时扫一遍「法定表达清单」:项目里会不会出现地图 / 疆界 / 国旗国徽 / 法条 / 医疗剂量 / 官方统计口径?有 → 先定官方源,再写代码。
- 给这类内容单独一条检查线,不与 UI 打磨混在一起;每次改动这个模块都重问一次内容源。
- 发布面要清算:这次是双发布面(Pages + Toy),Pages 推送即生效、Toy 要过审才生效 —— 下线时两个面都要处理,只推 git 等于只修了一半。
- 收到外部质疑时,先自己查一手标准,再决定怎么改;不要把 AI 的理由当依据(这次差点照「标准是 9 条」去改)。
- 跨项目通用规则已写进本机 memory(
china-map-compliance),下次在短片 / 海报 / 视频项目里碰到中国地图会直接生效。
关联文档
- 同族合规红线:H5移植微信小程序的要点与合规红线_v1 · 小红书导流话术合规红线_扣1领资料_v1
- 本次抽出的律:打磨不等于校验律_v1
- 同项目(风眼)平台侧事故:B站Toy同步事故复盘_版本指纹与外部cron兜底_v1
- 复盘方法:复盘事实先行原则 · Claude完成报告核查心法
- 交付诚实相关:交付前实测证伪律_v1
- 对外版(裸路径,不进图谱):
08_对外分发/我的台风站把海南岛画在了国界线外_自绘地图的合规红线_公开版.md - 项目底料(库外裸路径):
E:\typhoon-eye\assets\toy-runtime.js(文件头注释写有「不要再加回来」的原因)