新功能:照片探索器 · 查找任何已添加到地图的旅行照片。

工程日志

工程:从照片坐标到土地覆盖

表面上的光鲜背后,是一个用于量化证据、合并离线设备、一次性测量土地以及将私有源历史记录保离服务器的确定性流程。

由...设计。 6 分钟阅读
Maplight 照亮了由私人 Mapsake 旅行历史记录所代表的世界的各个部分。

Maplight 背后的产品问题。

访问过的国家地图可以回答一个有用的二元问题:这个地方是您历史的一部分吗?Maplight 问了其他问题。根据已定位的照片和其他旅行证据,该位置的哪些附近区域已经触及了这些时刻?

这听起来像是围绕点绘制半透明的圆圈。生产功能需要解决更复杂的问题:点可能会重叠,圆圈可能会跨越海岸线和边界,地球是球形的,数据来自多个系统,旧设备可能离线,并且整个库必须保持足够快速,以便进行交互式探索。

Maplight 的实现将这些方面分解为一个小型的、可移植的源模型、一个确定性的覆盖引擎和一个渲染层。 相同的输入应该产生相同的覆盖范围,无论历史记录是在一个设备上创建的,还是通过 iCloud 在多个设备上合并。

在持久化之前,对输入进行泛化。

原始输入可以开始于照片坐标、导入的行程、护照印章或手动记录的位置。 在 Maplight 来源持久化之前,Mapsake 会将其纬度和经度量化为六个字符的地理哈希单元格。 存储的来源包含该地理哈希、描述贡献源类型的位掩码以及已知的最早日期。

这提供了三个有用的属性。

首先,在同一小地理区域内重复出现的证据可能会合并为一个原始位置。其次,便携式记录是紧凑且确定的。第三,Maplight 模型不需要保留每个原始照片坐标才能重现照明。

最早的日期用于“历史”视图。 缺少日期的源仍然计入总结果,但不会被假定属于应用程序无法确定的年份。

显示2021年,被照亮的土地、国家和起源的总数的Maplight历史。

使合并为累加。

iCloud 同步不是单一的有序数据流。两个设备可以在离线状态下工作,记录相关数据,然后以不同的顺序接收重复数据。采用“最后写入者胜出”的机制可能会导致重要历史记录丢失。

而是,来源通过地理散列合并。源标志被组合,最早的有效日期优先。来源以排序的顺序编码在紧凑的块中。逻辑块由配置文件、世代和地理瓦片标识,而重组联合复制块的内容。

生成标识符在重建时非常重要。可以准备新的输出,而无需将以前的版本中的过时片段视为当前数据。这可以防止部分同步或中断的计算导致旧数据和新数据的混合。

合并规则是故意简单的:合并证据。简单、确定性的规则在需要将相同的私人历史记录在 iPhone、iPad 和 Mac 上进行合并时非常有用。

覆盖范围按等面积网格测量。

纬度和经度不代表在每个地方都相等的距离。经度在向两极移动时会缩小,因此计算普通的地图像素或大小为度数的单元格会导致结果因位置而异。

Maplight 使用大约 2 公里的等面积网格评估陆地覆盖率。每一行代表可比的物理区域,而照亮的范围存储为该行中的间隔。源半径成为候选单元格的范围;然后测试这些单元格并进行累积。

间隔可以使重叠变得廉价。如果附近的多张照片照亮相同的单元格,则引擎会合并运行,而不是重复计算土地。最终数字表示照亮的土地的并集,而不是每个圆的总和。

这也是为什么覆盖数字可能与数学圆的面积乘以来源数量不匹配的原因。海洋单元被删除,重叠被消除,并且边界归属可以将结果分配给国家/地区。

将海洋从总数中排除。

飞行照片或海岸访问可以将半径放置在水面上。Maplight 被描述为照亮的陆地,因此水不应过度膨胀数字。

覆盖范围引擎使用捆绑的边界几何来确定候选单元格是否位于陆地上以及位于哪个国家。 支持 Mapsake 的离线地图和 Gazetteer 功能的相同基本源系列,使该计算可以在不将坐标集发送到 Web 映射 API 的情况下可用。

沿海地区通常比内陆地区更复杂。岛屿、狭长的半岛、包围区域以及有争议的边界约定都会产生特殊情况。因此,引擎将覆盖范围视为在网格分辨率下的有用估计值,而不是测绘。

避免重复的属性覆盖。

国家总数是从与全球总数相同的覆盖单元格派生的。可以使用边界包含分配单元格,而全局联合继续将其计数一次。这使得国家细分可以解释,并防止与边界相邻的来源创建比地图实际覆盖的更多陆地。

来源分类与区域归属分开。地理哈希源可以记住,照片和手动添加的位置都相关,但围绕该合并源的突出显示单元仍然属于一个组。这种区分允许界面解释证据的来源,而不会将重叠的证据转换为重复的土地。

从存档快照创建时间线。

历史需要回答“本年度 Maplight 看起来是什么样的?”这个问题。在每次滑块移动时,从头开始重新计算每年都会耗尽电池电量并导致动画卡顿。

模型记录与当前世代和半径相关的年度快照。每个快照代表在或在截止日期之前的起源。未标记的起源仍然可用于查看所有时间,而不会被插入到虚构的历史年份中。

界面可以在准备好的总数和几何形状之间切换,同时保持地图响应的快速。当底层源集、所选半径或生成发生更改时,仍然会进行重建,但正常的播放读取稳定的序列。

使用模糊效果代替数千个圆形。

用户看到的是亮度,而不是网格单元。渲染层将计算的覆盖范围转换为可以与地图一起移动和缩放的叠加层。将整个世界视为单个超高分辨率纹理将消耗太多的内存;将每个源点作为独立的实时形状进行渲染会导致每帧重复处理重叠。

因此,Maplight 将昂贵的地理联合保持在循环之外,并以易于管理的块呈现准备好的覆盖范围。 覆盖层可以专注于呈现:颜色、不透明度、缩放和平滑过渡,而地理引擎负责地理答案。

此边界也有助于测试。可以在没有 SwiftUI 视图的情况下检查覆盖范围快照,并且可以在不更改合并语义的情况下调整渲染。

隐私塑造了架构。

将照片坐标上传到服务器并计算覆盖范围会更简单。Mapsake 故意不要求这种架构。量化发生在 Maplight 持久化之前,可以在具有捆绑土地几何的设备上构建覆盖范围,并且公共共享会导出通用的结果,而不是私有的原始集合。

这种选择将工作转移到用户的硬件,并使同步设计更加复杂。它还意味着系统可以在离线状态下保持有用,网站不会成为个人照片位置的仓库,并且删除或导出数据仍然与用户的 Mapsake 记录相关联。

Maplight 设置显示半径、私人朋友总数、重建和删除控件。

我们学到了什么。

关键的教训是,让每一层回答一个明确的问题:

  • “起源”解释了存在哪些通用的证据以及它们首次出现的时间。
  • 合并规则解释了多个设备如何融合,而不会丢失添加的内容。
  • 覆盖范围表示哪些等面积陆地单元格被显示。
  • 快照显示该集合随时间的变化。
  • 渲染是一种让结果看起来生动的技术。

Maplight 看起来有趣,因为其背后的机制经过了有意的简化。 简洁的输入、同步、面积测量、区间合并、分组边界以及准备好的快照,使得界面可以专注于情感部分:让某人通过照片观看地图上的生活,从而带来愉悦。

Mapsake 应用程序图标

Mapsake 的独立开发者,讲述了该应用程序背后的产品、地图、隐私和 Apple 平台工作。

创建您自己的旅行地图。

从您已经拥有的旅行历史开始。

Mapsake 免费,使用核心功能无需 Mapsake 帐户,并且支持的照片匹配功能都在您的设备上运行。

免费获取 Mapsake。