做了个 iOS App:把走路轨迹换算成「探索面积」,用网格统计你真正踩过多少土地

从一个憋了很久的问题说起

我平时喜欢在城市里乱走,周末没事就去一条没走过的街道溜达。用过不少轨迹类 App,但每次记录完,打开一看——就是地图上一条线。线很漂亮,过两天就忘了。打开相册找截图,发现我连哪条线是哪次走的都分不清楚。

更难受的是,这个问题一直没法回答:我到底探索了多少地方?

有次在上海徐汇一片老弄堂里绕了两个小时,绕出来的轨迹密密麻麻,我盯着那堆线,完全无法量化「自己覆盖了多大的世界」。轨迹记录的是路径,路径只告诉你「你去过这里」,却没法告诉你「你覆盖了多大的土地」——这两件事差很远。

于是我做了这款 App:雁过留痕(WingPrint)


核心思路:换一个度量单位

与其把走路的结果存成一条线,不如换算成面积

雁过留痕的核心逻辑是网格统计:把地图划分成约 25 米见方的格子(差不多一个篮球场边长),你走过哪里,哪里的格子就算作「已探索」,最终统计你真正踩过的土地面积,单位是 km²。

这么理解之后,「今天新开垦了 0.3 km²」就不抽象了——你在一个下午,踩实了将近五百个这样的格子。换个参照:上海静安区总面积约 7 km²,走了 0.3 km² 相当于覆盖了这个区 4% 的土地。比看步数直观多了。


技术选型与实现

App 是用 SwiftUI 写的,地图渲染用了 MapKit,网格计算和面积统计在本地完成。

后台 GPS 记录是最折腾的地方。iOS 对后台定位限制很严,处理不好要么耗电,要么用户锁屏走了十分钟回来发现没记到。我在轨迹分段逻辑里加了一个过滤:

// 有效出行段判断:GPS 点数不足 8 个不计入探索
func isValidSegment(_ points: [CLLocation]) -> Bool {
    guard points.count >= 8 else { return false }
    let distance = points.first?.distance(from: points.last ?? points[0]) ?? 0
    return distance > 50 // 至少移动 50 米
}

这个阈值说实话是「凑」出来的,不是精确算出来的——在自己几十次测试里表现还行,短暂误触或者停在原地开了一下 App 不会被错误计入「探索」。

行政区染色用的是内置的中国行政区边界数据,坐标系做了 GCJ-02 偏移适配,解锁省份时有一个整片染色的动画——我自己测试时看到陕西整片上色,还小小兴奋了一下。


成就系统和等级命名的三次推翻

纯记录工具有个问题:它是被动的,没有驱动力。所以我加了成就和等级系统,分三条轨道:探索系(累计面积)、坚持系(连续天数)、中国地理系(解锁省份/城市数)。

等级命名改了三版。第一版走「旅行者→探险家→地理学家」,感觉像小学生颁奖;第二版搞生物演化梗「草履虫→候鸟→迁徙者」,有朋友说「候鸟还行但草履虫我不想要」;最后定了「行者→远行者→纵览者」——现在看还是觉得差点意思,但想不到更好的,先上了再说。

桌面 Widget 也做了,实时显示当日探索进度和离下一等级还差多少面积。我自己用得最多的就是这个——每天早上往桌面一瞄,比看步数多了一点方向感。


适合谁用

不是所有人都需要这款 App。偶尔出去旅行想截图发朋友圈的,系统健康 App 就够了。

但如果你有「踩格子」的执念——就是那种看地图会想「这片我还没走过」「这个街区我要补一下」——面积加染色的逻辑可能会让你上瘾。Citywalk 爱好者、长期跑步骑行的人、喜欢自驾走遍各省的人,节假日回来看一眼「这趟走了多少 km² 的中国土地」,我觉得比发九宫格更有仪式感。


App Store 搜「雁过留痕」能找到,英文名 WingPrint,目前 1.15 版本,iOS 端。

如果你用过什么让自己觉得有成就感的记录工具,欢迎评论区聊聊——步数告诉你走了多远,面积告诉你占领了多少世界,我一直觉得后者更上瘾,但这事做对了挺难的。

posted @ 2026-04-25 20:17  samexxx  阅读(28)  评论(0)    收藏  举报