Инженерный журнал
Инженерия: От фотокоординат до охвата территории
За кажущейся простотой скрывается детерминированный конвейер для квантования данных, объединения автономных устройств, однократного измерения территории и защиты частной истории источников от сервера.
Вопрос о продукте, стоящем за Maplight.
Карта посещенной страны отвечает на полезный вопрос: является ли это место частью вашей истории? Maplight задает другой вопрос. Исходя из годов, указанных в расположенных фотографиях и других данных о путешествиях, какие близлежащие места достигли этих моментов?
Это похоже на рисование полупрозрачных кругов вокруг точек. Для реализации этой функции в рабочей среде необходимо решать более сложные задачи: точки могут перекрываться, круги могут пересекать побережья и границы, Земля имеет форму шара, данные поступают из нескольких систем, старые устройства могут быть отключены, и библиотека должна оставаться достаточно быстрой для интерактивного изучения.
Реализация Maplight разделяет эти аспекты на небольшую портативную модель источника, детерминированный движок обработки данных и слой рендеринга. Один и тот же ввод должен приводить к одному и тому же результату, независимо от того, был ли журнал создан на одном устройстве или объединен через iCloud на нескольких устройствах.
Обобщите входные данные перед сохранением.
Исходные данные могут быть фотографией с координатами, импортированным маршрутом, штампом в паспорте или вручную записанным местом. Прежде чем происхождение Maplight будет сохранено, Mapsake квантует его широту и долготу до ячейки геохеша из шести символов. Сохраненное происхождение содержит этот геохеш, битовую маску, описывающую типы источников, и самую раннюю известную дату.
Это предоставляет три полезных свойства.
Во-первых, повторяющиеся данные в одной и той же небольшой географической области могут быть объединены в одно исходное место. Во-вторых, портативная запись компактна и детерминирована. В-третьих, модели Maplight не обязательно должны сохранять все исходные координаты фотографии для воспроизведения освещения.
Самая ранняя дата используется в представлении «История». Источники без дат все равно учитываются в общей статистике, но они не приписываются году, который приложение не может установить.

Сделать слияние аддитивным.
Синхронизация с iCloud – это не единый упорядоченный поток данных. Два устройства могут работать в автономном режиме, записывать связанные записи, а затем получать дубликаты в разном порядке. Механизм «последней записи побеждает» может привести к потере важной истории.
Вместо этого, источники объединяются по геохэшу. Флаги источника объединяются, и самая ранняя допустимая дата имеет приоритет. Источники закодированы в отсортированном порядке внутри компактных блоков. Логический блок определяется профилем, поколением и географической плиткой, в то время как объединения реконсиляции дублируют содержимое блока.
Идентификатор поколения важен при восстановлении. Новые результаты могут быть подготовлены без учета устаревших фрагментов из предыдущей версии. Это предотвращает частичную синхронизацию или прерывание вычислений, которые могут привести к смешению старых и новых данных.
Правило объединения намеренно простое: объединение доказательств. Простые, детерминированные правила важны, когда одна и та же личная история должна быть согласована на iPhone, iPad и Mac.
Покрытие измеряется на сетке с равной площадью.
Широта и долгота не представляют собой одинаковые расстояния везде. Долгота уменьшается по мере приближения к полюсам, поэтому подсчет обычных пикселей карты или ячеек размером с градус приведет к искажению результата в зависимости от местоположения.
Maplight оценивает площадь покрытия на приблизительной сетке равных площадей в два километра. Каждая строка представляет собой сопоставимую физическую площадь, а освещенные участки хранятся в виде интервалов вдоль этой строки. Радиус источника становится диапазоном потенциальных ячеек; затем эти ячейки тестируются и суммируются.
Интервалы делают перекрытие недорогим. Если несколько близлежащих фотографий освещают одни и те же ячейки, движок объединяет последовательности, а не многократно подсчитывает землю. Окончательное число представляет собой объединение освещенной земли, а не сумму каждого круга.
Это также объясняет, почему число охвата может не совпадать с площадью математических кругов, умноженной на количество источников. Морские ячейки удаляются, перекрытия устраняются, и атрибуция границ может разделить результат между странами.
Исключите океан из общей суммы.
Фотография с самолета или посещение побережья может разместить радиус над водой. Maplight описывается как освещенная земля, поэтому вода не должна искусственно увеличивать количество.
Механизм определения области покрытия использует объединенную геометрию границ для определения, находятся ли потенциальные ячейки на суше и в какой стране они расположены. Та же базовая семейство источников, которое поддерживает автономные карты и справочник Mapsake, делает этот расчет доступным без отправки набора координат в веб-картографический API.
Береговые линии, как правило, более сложны, чем внутренние точки. Острова, узкие полуострова, анклавы и спорные границы создают особые случаи. Поэтому движок рассматривает покрытие как полезную оценку при его разрешении, а не как кадастровую съемку.
Покрытие атрибутов без двойного учета.
Общее количество стран вычисляется на основе тех же ячеек, что и общее количество по всему миру. Ячейке может быть присвоено значение с использованием граничного включения, в то время как глобальное объединение продолжает считать ее один раз. Это позволяет объяснить детализацию по странам и предотвращает ситуацию, когда источник, расположенный рядом с границей, создает больше суши во всем мире, чем фактически покрывает карта.
Разбивка источников отличается от атрибуции области. Геохеш-исходник может запомнить, что к нему относятся как фотографии, так и место, добавленное вручную, но выделенные ячейки вокруг этого объединенного исходника по-прежнему принадлежат к одной группе. Это различие позволяет интерфейсу объяснять, откуда взялись данные, не превращая перекрывающиеся данные в дублируемую территорию.
Создайте временную шкалу из сохраненных снимков.
История должна отвечать на вопрос: «Как выглядел Maplight в этот год?». Повторный расчет каждого года с нуля при каждом движении ползунка будет расходовать батарею и вызывать прерывистость анимации.
Модель сохраняет снимки состояния за каждый год, связанные с текущей версией и радиусом. Каждый снимок представляет собой источники, для которых самая ранняя дата находится в пределах или до указанной даты. Источники без даты остаются доступными для просмотра за все время, не добавляясь в вымышленный исторический год.
Интерфейс может затем переходить между подготовленными агрегатами и геометрией, сохраняя при этом мгновенную реакцию карты. Перестроение все равно происходит при изменении исходного набора, выбранного радиуса или поколения, но обычное воспроизведение считывает стабильную последовательность.
Вместо тысяч кругов используется эффект размытия.
Пользователь видит не ячейки сетки, а яркость. Слой рендеринга преобразует вычисленное покрытие в наложение, которое может перемещаться и масштабироваться вместе с атласом. Обработка всего мира как единой текстуры сверхвысокого разрешения потребовала бы слишком много памяти; рендеринг каждого источника как независимой живой формы приводил бы к повторной обработке перекрытий на каждом кадре.
Таким образом, Maplight удерживает дорогостоящую географическую обработку за пределами основного цикла и отображает подготовленные данные в удобных для обработки фрагментах. Наложение может сосредоточиться на представлении: цвете, прозрачности, масштабировании и переходах, в то время как движок обработки данных отвечает за географические вычисления.
Эта граница также помогает в тестировании. Снимок покрытия можно проверить без SwiftUI-представления, а рендеринг можно настроить без изменения семантики объединения.
Конфиденциальность повлияла на архитектуру.
Было бы проще загружать координаты фотографий на сервер и вычислять покрытие там. Mapsake намеренно не требует такой архитектуры. Квантование происходит до сохранения данных в Maplight, покрытие может быть построено на устройстве с использованием встроенной геометрии земли, а общедоступный обмен экспортирует обобщенный результат, а не частную исходную коллекцию.
Этот выбор переносит обработку на оборудование пользователя и делает проектирование синхронизации более сложным. Это также означает, что система может оставаться полезной в автономном режиме, веб-сайт не становится хранилищем личных фотографий, а удаление или экспорт данных остается связанным с вашей записью Mapsake.

Что мы узнали.
Главный урок заключался в том, чтобы каждый слой отвечал на один конкретный вопрос:
- Раздел «Происхождение» объясняет, какие общие доказательства существуют и когда они впервые появились.
- Правила объединения объясняют, как несколько устройств объединяются, не теряя добавленные данные.
- Покрытие показывает, какие ячейки суши с равной площадью отображаются.
- Снимки показывают, как это объединение меняется со временем.
- Рендеринг позволяет создать эффект живого изображения.
Maplight выглядит игриво, потому что скрытая под ним техника намеренно упрощена. Компактные элементы управления, синхронизация, измерение площади, объединение интервалов, сгруппированные границы и подготовленные снимки позволяют интерфейсу сосредоточиться на эмоциональной составляющей: позволить пользователю наблюдать, как фотографии оживляют карту.