Fog of World 是一对台湾开发者夫妇独立开发并在 年发布的应用,应用功能很简单,就是记录你走过的路的轨迹,并通过”擦除”的方式来呈现,颇有有点开拓世界的感觉。
应用不便宜,从原来的30到现在的163,并且因为应用需要在后台一直运行,对于电量本来就不富裕人iPhone来说就是雪上加霜。因此我也是直到21年伊始我才将其收入囊中,到现在已经连续在后台运行了一年多了。对于比较喜欢记录的人来说,这个过程确实是一个有意思的事情,去过什么地方,走过什么路,再次回看时总会勾起一些回忆。
自疫情开始后出去的机会就相对少了很多,以前去过的地方也不能自动地补录进应用内,事实上就连我也不知道去过哪些地方,是怎么走的,可是如果能把以前的去过的地方重新整理出来,是否就可以补全应用的路径呢?幸运的是,我去新的地方时,多少都会留下点照片,而照片本身是有GPS信息的,我准备利用这些坐标信息,重新将我的路径”再现”出来。
导出照片
既然要利用相片的GPS信息,首要事情就是需要把照片都导出来。我的照片基本上都是存放在手机/iCloud上面的,并且会用云盘和Google Photo备份。手机上并没有全部的相片,都在iCloud上,而iCloud拉胯的下载速度对于六七十G的照片大小来说是断然不合适的,毒盘同理,试着利用GooglePhoto的导出功能,结果有意外惊喜。
以前的GooglePhoto是无限容量的,多得如此我才能把所有的照片都上传到了GooglePhoto上,现在上传照片也会算到Driver的容量中。Photo的导出方法也很简单,设置那就有导出数据的配置。
并且可以选择按相册,时间等维度分批导出。从实用情况来看,不建议将所有照片一次导出,数据量大导出很可能失败,下载也困难。
导出后等一阵子就可以看到导出结果了,按提示下载即可。需要注意的是导出只能保留7天。
提取GPS信息
下到照片后,就可以着手提取照片中的GPS信息了。这事直接写一个小脚本来完成就可以,总体的思路是通过遍历目录下的照片,提取exif信息,并从中读取计算到GPS坐标信息,最后将提取到的信息都写到一个xls里。
这里我使用的是python(3)。
读取exif信息
JPG读取exif信息可以使用PIL获得,并遍历保存所有exif信息,用于后面的计算坐标信息。
1 | from PIL import Image |
因为苹果后期图片都是使用heic的格式保存了,需要结合pyheif与exifread来获取exif信息,并提取出我们想要的字段信息。
一个pyheif对象包含了以下信息:
- mode - the image mode, e.g. “RGB” or “RGBA”
- size - the size of the image as a (width, height) tuple of integers
- data - the raw decoded file data, as bytes
- metadata - a list of metadata dictionaries
- color_profile - a color profile dictionary
- stride - the number of bytes in a row of decoded file data
- bit_depth - the number of bits in each component of a pixel
而exif信息是保存在metadata里,结合exifread就可以exif信息读取出来。
1 | def get_exif_data_heic(img_path): |
特别的,如果想获取其他的exif信息,可以自行遍历1
2
3
4
5
6
7...
exifdata = exifread.process_file(fstream, details=False)
for tag in exifdata.keys():
print "Key: %s, value %s" % (tag, tags[tag])
...
GPS信息提取
拿到了exif信息后就可以提取其中的gps信息了。需要注意的是,虽然大家都是exif,但jpg提出来的信息与heic的不一样,在计算坐标时要分别处理。
JPG图片GPS计算
JPG的gps信息保存在exif信息的”GPSInfo”字段中。其包含的内容可以参考exif.tags。此处我们只需要拿到经纬度信息,所以参考前四个值即可。
参考上图,几个index的说明如下
- 1: 南北纬,”N”为北,”S”为南
- 2: 纬度信息
- 3: 东西经,”E”为东,”W”为西
- 4: 经度信息
而对于经纬度信息,它们分别包含了三个值, 分别是当前经纬度的”度(degrees),分(minutes),秒(seconds)”信息,所以获取到的经纬度信息不能直接使用,而是需要经过转换,其实就是把minutes与seconds转换在degrees就行了.
1 | lat = info[2] |
另外, 经纬度中表示中,东经为正,正经为负;北纬为正,南纬为负,还需要针对南纬、西经转换
1 | if info[1] == u'S': # south latitude |
如此,一般的jpg经纬信息就处理好了。
HEIC图片GPS计算
heic获取的exif信息里包含经纬度信息了,除了字段不一样,其他的格式与计算转换方式与jpg的别无二致。
1 | latitude_ref = exif.get('GPS GPSLatitudeRef') |
保存坐标信息
最后,只需要保存生成的坐标信息即可。这里我采用生成xls的方式,使用的是openyxl。
(此处只截取关键部分代码,完整可参考文未链接)
1 | from openpyxl import Workbook |
运行脚本
完整脚本可以参考这里
运行时需要先安装依赖库
1 | brew install python@3.9 libheif |
脚本会扫描同级目录下photos目录,并遍历子文件夹(影集),并以影集的方式生成xls。
生成的xls结果如下图
如此,便完成了数据收集的部分。
路径生成
Fog of World 有导入的功能,支持KML格式的文件。KML是用来描述地图中的坐标,海拔,甚至是自定义图形,不规则区域等信息的。既然GoogleEarth也支持这种格式,那生成KML这件事,还得劳烦老大哥才行。
另外需要注意的是,因为使用是照片的坐标信息,而这些信息其实都是单点的,如何利用这些单点的信息构成路径也是一个问题。
在旅行途中,拍照的点肯定是随着我的行程来推进的,一般情况下,我从一个点(这张图片)去到下一个点(另一张图片),期间可能涉及到位置转移,而转移要么是走路,要么是坐车,少部分是坐火车、飞机,甚至是长途巴士(20年疫情爆发时间曾试过从巴黎坐一晚上大巴来到米兰,非常可怕)
而无论是什么交通工具,都回归到我们日常中最常用的地图导航上来,而谷歌地图自然可以在A点与B点在我们选定交通工具的情况下为我们生成一条移动路径。虽然这样子生成出来的路径不一定就是我们当时所经历的,但因为总体移动方向都是八九不离十(因为AB点间一般相距不远)。
幸运的是,谷歌地图可以创建自定义的地图,其实就是类似于行程规划的一个功能,只不过我们这次的点是通过照片生成出来的而已。在菜单中选择”Your Places”就可以进入自定义地图的设置了。
进入自定义地图后,左侧就是配置的入口了,可以为自己的这次行程定一个名字,并且还支持直接导入数据。上一步生成的xls马上就可以派上用场了。
上传好xls后会自动把column解析出来,这里会有两次选择,第一次是用于选择坐标的字段,并需要选择是经度纬度哪个先哪个(因为是同一个字段)
而第二次选择的是生成点的名称应该用哪个字段去表示,最终会以这个名字展示在地图上。
导入后,坐标点就会在地图上显示。
接下来就是体力活了,我们需要在不同的点之间创建路径,点击任意一个点,会出现一个菜单,再点击”Directions to here”,就可以开始创建一个A/B点的交通规划,并且是可以选择不同的交通方式来规划路径。
然后再点击一个起始点,谷歌地图就会甚至A/B点以及选择的交通方式生成一条路径。
如此反复,就可以构建出这个影集的整个移动轨迹了。最后就可以生成KML了。
当然,这个过程中有一些需要注意的是,因为每创建一个路径就相当于添加了一个Layer,而每个自定义的地图不能支持无限多的L图层,所以如果是一条比较完整的路径,特别是那种交通方式是一致的情况下,可以直接在原来A/B点上添加C、D……点,以此来减少创建新图层。
另外分享一个小技巧,因为我们是在地图上创建一个路径,如果你导入的坐标点是天南地北的,一个是巴厘岛,另一个是俄罗斯,分散的点会干扰到你规划路径,且因为图层限制的问题,太多的点容易导致更多的图层,最后导致失败。我的处理办法是按影集去划分,而划分影集的方式要么就是地点,要么就是时间,我采用提前者。如这个影集只放巴厘岛的坐标,另一个影集放另一个地方的,一个影集对应一个自定义地图,一个自定义地图可以生成一份KML,如此一来规划会比较清晰,管理也方便。
最后,最重要的一点是,这些过程你都需要有比较准确的记忆,如在这里发生过什么(这个不难,因为已经有图片了),是怎么来到这个地方的,上一个地方是什么……等等,毕竟我们要创造的是回忆,现在回忆一下也不晚。
飞机轨迹
旅途中除了平常的活动外,飞机的移动也算是旅行的一部分,因此,飞机的移动轨迹也加进来也是顺理成章的事。但飞机的轨迹就比较简单了,因为不同的航班的航路基本上都是固定的,而且这些信息也是公开的,我们大可不必自己去”画”一条航路出来。这里介绍两个网站
它们都可以拿航班号,机场,航空公司的信息来查找线路,我的航班信息都可以在航旅纵横上查到所以可以直接拿航班号来获取航班的飞行轨迹。
以杭州-广州 CZ3502 航班为例,可以找到最近的飞行记录,如果已经飞了的就可以找到飞行信息。
Flightradar24
FlightAware
两个平台的使用大同小异,免费用户最多只能看最近几天的记录,有试用的可以用试用,尝试找回更久以前当天你飞行的航班。但如果太久了也没啥事,如上所说,只要航班号还在,那其实找最近的飞行记录也是没差的。
说一千道一万,最后虽然我把能导的记录都导出来了,但最后到底是没用,因为飞行记录太杂太乱太多太长了,而且比起在地面上移动,在天上移动时并不会对当前路线有任何的感觉。网上冲浪时还发现有人甚至还想把飞行轨迹去掉,至此我是可以理解了。
(这是只导入飞行轨迹后生成的图,不是很完整,但如果与正常的轨迹一齐就会显得非常乱)
导入Fog of World
把所有生成的、下载的KML都放到iCloud(或者其他的支持的网盘上),然后同步即可。
总结
整个补全计划其实并不复杂,比较顺利的一个原因是我平常就比较注意照片的管理,每次行程出游都会对旅途中的照片分门别类,并按时间线等排好,经过过多次的数据丢失后,我对数据本身的敏感度安全感比较低,而作为回忆的载体,自然需要好生呵护,以后翻看才能历久常新。