大圆插值原理:Timeline Visualizer的飞行轨迹为什么不会「瞬移」跨洋
【免费下载链接】google-timeline-visualizerVisualize your year in travel using your Google Location History (Timeline) data项目地址: https://gitcode.com/GitHub_Trending/go/google-timeline-visualizer
Timeline Visualizer是一款把你的 Google 地图时间线(Location History)导出文件变成动画旅行视频的开源工具。当数据里包含跨洋飞行时,它用大圆插值算法让镜头沿着航线弧线平滑掠过,而不是从出发城市直接"瞬移"到目的地——同一套算法在 Android、桌面 Python CLI 和 iPhone 网页版上行为完全一致。
为什么长途飞行会在地图上"瞬移"?
Google 时间线是按间隔记录位置点的。飞行途中 GPS 往往只留下起降两端各一个点,于是两个相邻坐标之间可能相隔 8000 公里——例如首尔和宿务之间,项目自带的示例数据 seoul-bohol-sample.json 正是这种场景。
如果直接用两点连线(经纬度线性插值),会有两个问题:
- 屏幕上标记物一瞬间"闪现"到目的地;
- 平面地图上的直线并不符合真实航线——地球表面上两点间的最短路径是一段弧线,不是直线。
什么是大圆插值?
大圆:地球表面上的最短路径
用过球心的平面去切球体,得到的圆叫大圆(赤道和所有经线圈都是大圆)。球面上任意两点之间的最短路线,就是连接它们的那段大圆弧——这正是民航航班的实际飞行方式,航空地图上那些"弯弯曲曲"的航线其实是大圆在平面投影下的样子。
slerp:按角度插值,而不是按坐标差
"插值"就是根据进度比例求路径上的某个点。Timeline Visualizer 用的是球面线性插值(Slerp),原理只需四步:
- 把起点、终点各自换算成单位球上的三维单位向量(经纬度 → x、y、z);
- 用点积 + 反余弦求出两个向量之间的夹角 ω;
- 进度为 f 时,取权重
sin((1−f)·ω)/sinω与sin(f·ω)/sinω; - 对两个向量加权求和,得到大圆上进度 f 处的位置,再反算回经纬度。
一句话类比:普通线性插值是在坐标表里"拉一条直线",slerp 则是"在三维空间里沿圆弧走路"。由于角度均匀分布,标记物在画面上的移动速度也是均匀的,这正是"掠过"而非"瞬移"的来源。
这个算法还做了两处稳健性处理:进度在端点(f=0 或 1)时直接返回原坐标,保证衔接无跳变;两点几乎重合时自动退化为普通线性插值,避免除法不稳定。
Timeline Visualizer 里的工程实现
三个平台的实现算法一致,这也是项目"平台一致性"测试关注的核心内容之一:
- Android(Kotlin):
Journey.interpolate,位于 TimelineModels.kt - 桌面 CLI(Python):
interpolate_latlon,源码注释原话是 "so long hops sweep instead of teleporting"(长距离跳跃要掠过而不是瞬移),见 visualizer.py - iPhone 网页版(TypeScript):
greatCircleReferenceX,见 geo.ts
实现分三步走 👇
第 1 步:先识别"哪一段是飞行"
并不是每两个点之间都做大圆插值,只有被判定为**转移段(transfer)**的长跳跃才需要。项目使用动态阈值:
| 参数 | 取值 | 含义 |
|---|---|---|
| 最小转移距离 | 60 km | 低于此值视为普通移动 |
| 最大转移距离 | 120 km | 阈值上限 |
| 典型采样倍数 | 3× | 跳跃距离须达到旅程常规采样间距的 3 倍 |
常量定义见 TimelineModels.kt,Python 端同名常量在 visualizer.py。效果是:坐地铁不会被画成"大圆弧",而 8000 公里的航班则一定会被识别出来。
第 2 步:把长航段切成大量渲染步
一个飞行段不是一笔画完的。渲染器限制每步不超过 75 km、单段最多 320 步(MAX_RENDER_STEP_KM/MAX_STEPS_PER_SEGMENT,见 TimelineModels.kt)。每一步的位置都用 slerp 求解,整段飞行于是变成一条密集、均匀、平滑的弧线。
第 3 步:镜头跟随弧线移动
视频中,标记物沿弧线连续移动,镜头带"死区"跟随:日常通勤的小幅移动不会触发镜头抖动,跨洋航班则呈现为一次连续扫过——相关说明见 README.md。
极地航线:一个额外的边界情况
靠近两极时经度变化极快,常规的"展开地图"算法可能把一段极地飞行误判成"多绕了世界一圈"。网页版专门识别"极地走廊"(纬度 ≥ 50° 的连续段),用两端点之间的大圆参考位置校正整段走廊的经度走向,见 unwrapJourneyPoints。这是"大圆即最短路径"在工程上的又一处应用。
动手体验:生成一支飞行掠过视频
- 在手机上导出
Timeline.json(位置设置 → 时间线 → 导出数据); - 用 Android 应用或 iPhone 上的网页版打开(步骤详见 README.md 与 web/README.md);
- 选择一段包含长途飞行的日期区间,预览后生成 MP4。
小结
- 地球表面两点间的最短路径是大圆弧,Slerp 按角度在大圆上均匀取点;
- Timeline Visualizer 先用 60–120 km 的动态阈值识别飞行转移段,再按每步 ≤ 75 km 切分,逐点做大圆插值;
- Android / Python / 网页三端算法一致,轨迹在任何设备上都不会"瞬移"跨洋;
- 插值只影响显示与动画,你的原始时间线数据保持不变,隐私无忧。
【免费下载链接】google-timeline-visualizerVisualize your year in travel using your Google Location History (Timeline) data项目地址: https://gitcode.com/GitHub_Trending/go/google-timeline-visualizer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考