前言一个搁置了两年的想法我大学时候喜欢骑车在城市里乱逛每到一个新地方就在手绘地图上涂一小块像玩现实版的战争迷雾游戏。后来工作了偶尔用运动App记轨迹但看着那些线叠在地图上总觉得缺了点什么。直到有一天我盯着跑步App里密密麻麻的轨迹线发了会儿呆突然想明白一件事线是线面积是面积。你沿着同一条路跑了一百遍轨迹记录得再漂亮你真正探索过的地方其实没增加。我想要的不是记录我走过哪条路而是**“我到底覆盖了多少土地”**。这两个问题看着像其实差别很大。于是我做了「雁过留痕」——一个iOS App核心概念只有一句话把你走过的地方换算成探索面积单位是 km²。25米网格听起来简单粗暴调起来真不简单实现面积这个概念比我预期难得多。最早我试过用轨迹围成的多边形来算面积结果发现你走个来回根本围不成像样的形状算出来的数字毫无意义。后来换了思路把地图切成 25m × 25m 的小格子人经过一个格子就算点亮一个。探索面积 点亮的格子数 × 每个格子的面积。这个方案效果出奇地好——你在街上走地图上会像素画一样慢慢铺开一片颜色直觉上就是这块地方我踩过了。25米这个精度是一轮轮试出来的50米太粗你明明没走到对面那条街格子已经亮了10米数据量爆炸手机存储扛不住25米刚好是精度和性能的平衡点GPS 轨迹记录本身用的是 iOS 的CoreLocation后台定位能力这套 API 比较成熟关键是在电量和精度之间找平衡。我在内部的指标追踪模块里监控了很多维度——总距离、总时长、记录天数、连续打卡天数、夜间出行次数、周末记录天数等等这些数据最后都会喂给成就系统。这里分享一下核心的网格计算逻辑思路不复杂但很关键structGridCell:Hashable{letx:Intlety:Int}funcgridCell(forcoordinate:CLLocationCoordinate2D,gridSize:Double25.0)-GridCell{// 将经纬度投影到平面坐标后按 gridSize 取整letmetersPerDegreeLat111_320.0letmetersPerDegreeLon111_320.0*cos(coordinate.latitude*.pi/180)letxInt(floor(coordinate.longitude*metersPerDegreeLon/gridSize))letyInt(floor(coordinate.latitude*metersPerDegreeLat/gridSize))returnGridCell(x:x,y:y)}// 探索面积 去重后的格子数 × 单格面积letexploredAreaDouble(uniqueGridCells.count)*0.000625// 25×25 625m² 0.000625km²逻辑不难理解把每个 GPS 坐标点映射到对应的网格用Set去重最后乘以单格面积就是总探索面积。真正麻烦的是工程层面的问题——后台定位的频率控制、大量格子数据的持久化性能、以及地图渲染时怎么高效绘制数万个已点亮格子。省份解锁比想象中上头做着做着发现光有面积数字还不够爽。你告诉用户你探索了 12.7km²他可能没什么概念。但如果你说**“你已经解锁了 3 个省份、15 个城市”**感觉就完全不一样了。所以我内置了中国行政区的边界数据做了省市解锁的玩法。轨迹落在哪个省、哪个市系统自动识别地图上对应区域被染上颜色。这里有个经典的坑国内地图的坐标偏移问题GCJ-02。GPS 拿到的是 WGS-84 坐标不做转换的话你在上海走的路可能飘到黄浦江里去。这个适配花了不少时间做国内地图相关开发的同学应该都踩过这个。成就徽章也是自然长出来的功能。我在代码里按不同维度分了好几个 trackTrack含义示例exploration探索类累计探索面积达到 10km²consistency坚持类连续记录 30 天china中国版图类解锁 10 个省份world世界探索类足迹覆盖 3 个国家每个 track 下面又分多个系列每个系列有多个层级。比如连续记录 7 天解锁一个徽章30 天又是一个90 天又是一个。做这套东西的时候自己都上瘾了——有一次周末专门绕远路走了一段没去过的巷子就为了多亮几个格子。数据安全数据是用户的不是我的做这种长期积累型的 App最怕数据丢失。你攒了大半年的探索面积换个手机没了用户肯定跟你急。所以我做了本地备份导出格式是自定义的.wingprintBackup底层是 JSON同时也支持GPX 格式导出方便用户在其他平台使用。这个决定其实挺纠结的。GPX 导出意味着用户可以把数据带走对留存来说不是好事。但我觉得数据是用户的不是我的。独立开发者跟大厂不一样没必要靠锁数据留人。一些做得还不错的功能和坦白的问题做得还不错的桌面 Widget显示当日进度和累计面积这个好评率挺高路线回放选一条历史轨迹在地图上像看动画一样回放你的路线。去年十一出去玩回来看了一遍自己的行程回放有点像用上帝视角重走了一遍坦白说的问题现在下载量不大。一个没有推广预算的新 App在 App Store 里就是沧海一粟。而且探索面积这个概念需要解释成本不像记步或者打卡那么直觉。社交分享卡片一直想做——让用户一键生成好看的探索报告图比如2024年我走过了 XX km²解锁了 XX 个城市——还在打磨中。写在最后有个用户评论说“人生总要留下一些什么走过的路见过的人看过的风景。”我看到这条评论的时候愣了一下觉得这个 App 没白做。如果你也是那种喜欢在城市里乱逛、走没走过的路、发现犄角旮旯小地方的人可以在 App Store 搜「雁过留痕」试试。它是一个纯 iOS 原生 AppSwift 开发目前还是我一个人在做。另外也想和社区里的开发者交流几个技术方向大规模网格数据的存储优化目前用的 Core Data数据量上去之后查询性能是个挑战、后台定位的省电策略、以及地图上大量自定义图层的渲染性能。如果你有相关经验欢迎评论区聊聊。你所在的城市你觉得自己探索了百分之几