gods-eye-view 交通流测试夹具:用真实 TomTom MVT 切片做离线解码与无密钥回归验证
【免费下载链接】gods-eye-viewA spy satellite simulator in your browser, except the data is real. Live open source spatial intelligence on a photorealistic 3D globe.项目地址: https://gitcode.com/GitHub_Trending/go/gods-eye-view
本文围绕 gods-eye-view 仓库中 src/data/fixtures/README.md 所记录的测试夹具tomtom-flow-austin-12-935-1686.pbf展开,说明这段真实采集的 TomTom 交通流矢量切片如何被用于离线单元测试与无密钥浏览器回归测试。读完本文,你将掌握该夹具的来源、数据结构、在decodeFlowTile与切片数学中的用法,以及通过qa-traffic --fixtures模式进行确定性验证的完整方法。
夹具是什么:一段真实的 TomTom 交通流矢量切片
仓库的 src/data/fixtures/ 目录中存放着多个测试数据文件,其中 tomtom-flow-austin-12-935-1686.pbf 是README.md唯一重点记录的对象。它的关键事实如下:
| 属性 | 值 |
|---|---|
| 文件类型 | Mapbox Vector Tile(MVT)protobuf,图层名为"Traffic flow" |
| 数据来源 | TomTom 交通流相对速度切片(relative风格) |
| 地理位置 | 美国奥斯汀市中心(downtown Austin) |
| 切片坐标 | z12 / x935 / y1686(Web Mercator slippy 坐标系) |
| 采集时间 | 2026-07-16 |
| 上游地址 | api.tomtom.com/traffic/map/4/tile/flow/relative/12/935/1686.pbf |
| 文件大小 | 22,980 字节 |
| 版权 | © TomTom |
这段数据不是手工构造的假数据,而是从 TomTom 上游接口真实抓取并原样归档的响应体。它代表的是2026-07-16 某一时刻的交通拥堵快照(point-in-time congestion snapshot),这一点在 README 中被反复强调:它不是随应用打包的数据图层,也不会在应用普通启动时被加载。
夹具在仓库中的定位与边界
README 明确指出该夹具的两种使用场景:
- 离线解码 / 数据源测试(offline decode/source tests)——不依赖网络与 API Key,直接对本地文件做解码断言;
- 显式的
qa-traffic --fixtures浏览器模式——用于无密钥的确定性回归验证。
同时 README 也划清了边界:该文件是"快照"而非"数据层",普通应用启动流程绝不会读取它。这意味着它只服务于测试路径,src/data/fixtures/目录下同级的firms-csv-cases.json、firms-viirs-noaa20-sample.csv也是同类定位的测试数据,只是未被 README 展开记录。
离线解码验证:夹具驱动的单元测试
夹具最主要的消费方是 src/data/flowTiles.test.mjs。该测试文件直接读取fixtures/tomtom-flow-austin-12-935-1686.pbf,并针对解码函数decodeFlowTile(定义于 src/layers/traffic/flowDecode.js)做了一系列真实数据断言:
- 解码产出量:从该夹具中至少解出 50 条以上流线段(segments);
- 数值域合法:每条线段的
trafficLevel都在[0, 1]区间内且为有限数——这是 TomTom 当前速度与自由流速度的比值(1 表示自由流); - 坐标地理范围:所有坐标点都落在奥斯汀范围(
lon ∈ [-98.0, -97.5],lat ∈ [30.0, 30.5]),证明解码结果确实还原为奥斯汀市中心的真实路网; - 拥堵真实存在:至少存在一条
trafficLevel < 1的线段,说明夹具携带了真实的拥堵信息; - 结构完整性:每条线段形状为
{ coords, trafficLevel, roadType, closure },且夹具中至少包含一条closure === true的封闭路段,覆盖了道路封闭解码分支; - 防御性:对非 MVT 缓冲区调用
decodeFlowTile返回[],不会抛异常。
从解码实现(flowDecode.js)可以看到细节:它用pbf@5的PbfReader加@mapbox/vector-tile@3的VectorTile解析 MVT,提取名为"Traffic flow"的图层;缺少或非法的traffic_level字段会被跳过,除非road_closure为真(封闭路段以 level 0 解码);单个损坏 feature 会跳过而非拖垮整个切片。
切片数学:z12/x935/y1686 从何而来
夹具坐标并非随意选取。src/data/tomtomTiles.js 实现了纯函数的 Web Mercator slippy 切片数学(lonLatToTile、tileToBBox、tilesForBounds),而 src/data/tomtomTiles.test.mjs 用奥斯汀市中心坐标(30.2672, -97.7431)对夹具坐标做了双向验证:
lonLatToTile(-97.7431, 30.2672, 12)精确得到{x: 935, y: 1686},与夹具文件名一致;tileToBBox(12, 935, 1686)的包围盒包含奥斯汀市中心,且中心点经lonLatToTile往返计算仍回到{x: 935, y: 1686};- 以该坐标为中心的 0.05° 视口经
tilesForBounds计算,返回 1~4 个切片且必然包含夹具切片; - 横跨切片边界的包围盒返回
[935, 936]两个切片,验证了切片枚举的正确性。
此外tomtomTiles.js还承载了代理侧的预算账本逻辑(utcDayKey、normalizeBudget、isOverBudget),由 tomtomTiles.test.mjs 覆盖:UTC 日期键格式、跨日清零、损坏状态重置、达到软上限后拒绝请求等。这套数学是"零依赖、无 Cesium"的,客户端(src/data/flowTiles.js)与服务端代理可以共享同一份实现做单元测试。
无密钥浏览器模式:qa-traffic --fixtures
夹具的第二个用途是 scripts/qa-traffic.mjs 的--fixtures模式。该脚本本体的头部注释明确了这一模式的设计意图:"Add--fixturesfor synthetic roads and the recorded flow tile without a key"——即不需要 API Key、不触碰上游网络、不消耗配额的确定性验证。
其实现机制位于 scripts/traffic-fixtures.mjs:
- 启动时用
readFileSync读取夹具.pbf; trafficFixtureResponse(request)作为 Puppeteer 请求拦截回调,把三类请求"假造"出来:/api/tomtom/status→ 返回{hasKey: true, dailyCount: 0},伪装成有密钥的服务端;/api/tomtom/flow/{z}/{x}/{y}.pbf→ 原样返回夹具字节,Content-Type 为application/x-protobuf;/api/overpass中带highway的查询 → 用tilesForBounds+decodeFlowTile从夹具解出的真实路段坐标合成 synthetic roads(截取前 240 条 way,并附加一条 residential 路段作为兜底),从而在无 Overpass 网络的情况下驱动整个 traffic 图层渲染。
关键点在于 scripts/qa-traffic.mjs 与脚本内对夹具模式的刻意区分:FIXTURES模式下预算断言((iii))被标记为INCONCLUSIVE,并在启动日志中声明 "Synthetic source mode; live quota was not exercised"——夹具模式不验证实时源访问与配额记账,它只负责把渲染链路、参数切换、无密钥降级等行为以确定性的方式跑通。这也与 README "point-in-time snapshot" 的定性一致。
背后的实时链路:代理、缓存与预算(夹具对应的生产路径)
夹具是测试替身,但它的"正主"是一条完整的实时链路,理解它有助于理解夹具为什么值得被归档。server/providers/traffic.js 是 TomTom 交通流矢量切片的本地代理(Vite 插件):
- 上游:
api.tomtom.com/traffic/map/4/tile/flow/relative/{z}/{x}/{y}.pbf,Key 只存在于服务端TOMTOM_API_KEY,浏览器同源访问/api/tomtom/flow/{z}/{x}/{y}.pbf,Key 永不落浏览器; - 缓存:内存(最多 256 条)+ 磁盘(
.gev-cache/tomtom/),TTL 120 秒,每切片单飞(single-flight),上游失败时 serve-stale;缓存命中不计入预算; - 预算治理:持久化计数器(
.gev-cache/tomtom/budget.json,按 UTC 日期键控、跨日归零),软上限默认TOMTOM_DAILY_TILE_BUDGET= 40,000(免费档约 5 万/天),超限后有旧数据则发STALE-BUDGET,否则返回429 {error:'budget'}; - 无密钥降级:
/api/tomtom/status返回{hasKey:false, ...},tile 端点返回503 {error:'no_key'}且不触上游,traffic 图层据此进入模拟模式——qa-traffic的(v)场景正是用请求拦截伪造{hasKey:false}来验证这一降级路径,包括"零 flow 请求发出"与"loadingLabel 以 SIMULATED 开头"。
客户端侧,src/data/flowTiles.js 通过 src/layers/traffic/flowSource.js 的createFlowTileSource拿到fetchFlowForBounds:按tilesForBounds并行拉取覆盖切片、在客户端解码、以z/x/y为键缓存 120 秒(最多 64 条,最旧淘汰);局部失败返回已解码部分(last-good),全部失败才 reject。flowTiles.test.mjs用夹具验证了请求路径(/api/tomtom/flow/12/935/1686.pbf)、缓存命中不再二次请求、AbortSignal中止与 503 拒绝等行为。
如何运行这些验证
夹具相关的验证无需任何 API Key,可直接在仓库根目录执行:
# 离线解码与切片数学单元测试(node:test) node --test src/data/flowTiles.test.mjs src/data/tomtomTiles.test.mjs # 无密钥浏览器回归:合成路网 + 录制切片(需要已启动的 dev server) node scripts/qa-traffic.mjs --url http://localhost:4410 --fixtures运行qa-traffic --fixtures时,脚本会以--use-gl=angle --use-angle=swiftshader等参数启动无头 Chromium(优先使用 Puppeteer 版本固定的 Chrome-for-Testing,见 scripts/qa-traffic.mjs 的注释说明),驱动真实应用跑完 live 模式、uncoveredRoads参数切换、斜视取景框、预算诚实性与无密钥降级五组断言,并输出qa-shots/traffic-*.png截图(gitignored),任何 FAIL 都会以非零退出码结束。
使用与分发注意
README 在结尾标注了© TomTom,这提示了夹具的许可边界:它是从 TomTom 公开接口采集的样本数据,仅供仓库内离线测试与验证使用,不应作为随应用分发的数据图层,也不应被普通启动流程加载。如需扩展测试覆盖,可在遵守上游许可的前提下按同样的方式录制新切片(如其他城市、其他 zoom 级别),并在 src/data/fixtures/README.md 中补充来源、坐标、采集时间与大小等元信息,保持测试数据的可追溯性。
【免费下载链接】gods-eye-viewA spy satellite simulator in your browser, except the data is real. Live open source spatial intelligence on a photorealistic 3D globe.项目地址: https://gitcode.com/GitHub_Trending/go/gods-eye-view
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考