Пример рабочего процесса для анализа векторных геопространственных данных
TL;DR
Показан конвейер геопространственной аналитики в логике bronze/silver/gold: сырые геоданные → единая витрина → материализованные результаты.
Разобраны практические проблемы подготовки: приведение разных систем координат к единому стандарту (например, WGS84), поиск и исправление некорректных геометрий.
Для масштабирования геопространственных соединений предложены приёмы вроде упрощения геометрий и аппроксимаций через геоиндексацию H3.
Слой представления зависит от потребителя: GeoJSON для ГИС/веб-карт или звёздная схема/таблицы для BI.
Отдельно приведён пример высокоуровневой архитектуры платформы данных в Azure, показывающий типичные интеграции и место геопространственных витрин в общей модели данных.

Большинство данных, которые описывают измеримые процессы в реальном мире, так или иначе имеют геопространственную составляющую. Организации, которые управляют активами на большой географической территории или выстраивают бизнес-процессы с учётом множества слоёв географических атрибутов, которые нужно отображать на карте, сталкиваются с более сложными требованиями к геопространственной аналитике, когда начинают использовать эти данные для ответов на стратегические вопросы или оптимизации. Такие организации, ориентированные на геоаналитику, могут задавать своим данным, например, такие вопросы:
Сколько моих объектов попадает в заданные географические границы?
Сколько времени занимает у моих клиентов дорога до объекта — пешком или на машине?
Какой плотности пешеходного трафика мне стоит ожидать на единицу площади?
Все это — важные геопространственные запросы, для которых необходимо, чтобы множество сущностей данных были интегрированы в общий слой хранения, а геопространственные соединения, такие как операции «точка в полигоне», и геопространственная индексация могли масштабироваться под соответствующие объёмы входных данных. В этой статье рассматриваются подходы к масштабированию геопространственной аналитики с использованием возможностей Databricks и открытых инструментов, работающих поверх Spark, общего формата хранения таблиц Delta и Unity Catalog [1], с фокусом на пакетной аналитике по векторным геопространственным данным.
Обзор решения
Диаграмма ниже суммирует открытый подход к построению геопространственного Lakehouse в Databricks. Через различные режимы загрузки (часто через открытые API) геопространственные наборы данных попадают в облачное хранилище в разных форматах; в случае Databricks это может быть том (volume) внутри каталога и схемы Unity Catalog. Основные форматы геоданных включают векторные форматы (GeoJSON, .csv и шейп-файлы .shp), которые представляют точки, линии или полигоны с парами широта/долгота и атрибутами, а также растровые форматы (GeoTIFF, HDF5) для данных изображений. Используя GeoPandas [2] или основанные на Spark геопространственные инструменты, такие как Mosaic [3] или H3-функции Databricks SQL [4], мы можем готовить векторные файлы в памяти и сохранять их в унифицированном «бронзовом» слое в формате Delta, используя Well Known Text (WKT) как строковое представление любых точек или геометрий.

Если приземление в бронзовый слой играет роль журнала аудита загруженных данных, то переход от «бронзы» к «серебру» — это этап, на котором выполняется подготовка данных и любые геопространственные соединения, общие для всех последующих сценариев использования. Готовый «серебряный» слой должен представлять собой единую геопространственную витрину и при необходимости может интегрироваться с другими, негеопространственными наборами данных в составе корпоративной модели данных. На этом же этапе появляется возможность консолидировать несколько таблиц из бронзового слоя в ключевые геопространственные наборы данных с несколькими атрибутами и геометриями на базовом уровне детализации, необходимом для дальнейших агрегаций.
«Золотой» слой затем становится геопространственным слоем представления, где хранятся результаты геопространственной аналитики, такие как расчёты времени в пути или плотности. Для использования в инструментах построения дашбордов, таких как Power BI, результаты могут материализовываться в виде звёздных схем (star schema), в то время как облачные GIS-решения, такие как ESRI Online, предпочитают GeoJSON-файлы для конкретных картографических приложений.
Подготовка геопространственных данных
В дополнение к типичным проблемам качества данных, которые возникают при объединении множества разрозненных источников в архитектуре озера данных (пропуски, различающиеся практики записи и т.п.), у геопространственных наборов данных есть и свои специфические задачи по качеству и подготовке. Чтобы векторные геопространственные наборы данных были совместимы между собой и их было легко визуализировать на последующих этапах, лучше заранее выбрать единую систему географических координат, например WGS 84 (широко используемый международный стандарт GPS). В Великобритании многие открытые геопространственные наборы данных используют другие системы координат, такие как OSGB 36, оптимизированную для более точного отображения географических объектов именно в пределах Великобритании (часто в формате «восточное» и «северное» смещения — Eastings и Northings — вместо более привычных пар широта/долгота). Для таких наборов данных требуется преобразование в WGS 84, чтобы избежать неточностей на последующих этапах картографирования, как показано на рисунке ниже.
![Обзор геопространственных систем координат a) и наложение WGS 84 и OSGB 36 для Великобритании b). Изображения адаптированы из [5] с разрешения автора. Copyright (c) Ordnance Survey 2018. Обзор геопространственных систем координат a) и наложение WGS 84 и OSGB 36 для Великобритании b). Изображения адаптированы из [5] с разрешения автора. Copyright (c) Ordnance Survey 2018.](https://habrastorage.org/r/w780/getpro/habr/upload_files/49e/583/9a5/49e5839a57d7743a96c8c05252d90e9c.png)
Большинство геопространственных библиотек, таких как GeoPandas, Mosaic и другие, имеют встроенные функции для выполнения таких преобразований, например, как в документации Mosaic:
df = (
spark.createDataFrame([{'wkt': 'MULTIPOINT ((10 40), (40 30), (20 20), (30 10))'}])
.withColumn('geom', st_setsrid(st_geomfromwkt('wkt'), lit(4326)))
)
df.select(st_astext(st_transform('geom', lit(3857)))).show(1, False)
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------
|MULTIPOINT ((1113194.9079327357 4865942.279503176), (4452779.631730943 3503549.843504374), (2226389.8158654715 2273030.926987689), (3339584.723798207 1118889.9748579597))|
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Преобразует мульти-точечную геометрию из WGS84 в формат проекции Web Mercator.
Ещё одна проблема качества, характерная именно для векторных геопространственных данных, — это понятие некорректных геометрий, приведённое на рисунке ниже. Такие некорректные геометрии ломают GeoJSON-файлы или аналитические расчёты выше по потоку, поэтому их лучше исправить или при необходимости удалить. В большинстве геопространственных библиотек есть функции для поиска и попытки исправления некорректных геометрий.
![Примеры типов некорректных геометрий. Изображение взято из [6] с разрешения автора. Copyright (c) 2024 Christoph Rieke. Примеры типов некорректных геометрий. Изображение взято из [6] с разрешения автора. Copyright (c) 2024 Christoph Rieke.](https://habrastorage.org/r/w780/getpro/habr/upload_files/9d6/1f8/025/9d61f80250c6caf98cccb60f7acb9620.png)
Эти шаги по обеспечению качества и подготовке данных стоит выполнять на ранних этапах внутри слоёв Lakehouse; я обычно реализовывал их на этапе перехода от «бронзы» к «серебру» вместе с любыми переиспользуемыми геопространственными соединениями и прочими преобразованиями.
Масштабирование геопространственных соединений и аналитики
Геопространственный аспект «серебряного» / корпоративного слоя в идеале должен представлять собой единую геопространственную витрину, которая питает все верхнеуровневые агрегации, аналитику, ML-модели и AI-сценарии. В дополнение к проверкам и улучшению качества данных, иногда имеет смысл консолидировать множество геопространственных наборов данных через агрегации или объединения, чтобы упростить модель данных, упростить запросы на последующих этапах и избежать необходимости заново выполнять дорогостоящие геопространственные соединения. Геопространственные джойны часто оказываются вычислительно очень затратными из-за большого объёма битов, необходимых для представления порой сложных мультиполигональных геометрий, и из-за необходимости выполнять множество попарных сравнений.
Существует несколько стратегий, позволяющих сделать такие соединения более эффективными. Например, можно упростить сложные геометрии, фактически сократив количество пар широта/долгота, необходимых для их описания; для этого существуют разные подходы, заточенные под разные цели (например, сохранение площади или удаление избыточных точек), и они реализованы в библиотеках, например в Mosaic:
df = spark.createDataFrame([{'wkt': 'LINESTRING (0 1, 1 2, 2 1, 3 0)'}])
df.select(st_simplify('wkt', 1.0)).show()
+----------------------------+
| st_simplify(wkt, 1.0) |
+----------------------------+
| LINESTRING (0 1, 1 2, 3 0) |
+----------------------------+
Другой подход к масштабированию геопространственных запросов — использование системы геопространственной индексации, как показано на рисунке ниже. Если агрегировать данные по точкам или полигонам в систему геопространственных индексов, такую как H3, то приближённое представление тех же данных можно получить в сильно сжатом виде — в форме короткого строкового идентификатора. Этот идентификатор сопоставляется с набором фиксированных полигонов (с визуализируемыми парами широта/долгота), покрывающих земной шар набором шестиугольных/пятиугольных областей разных разрешений, которые можно агрегировать вверх и вниз по иерархии.
![Мотивация для использования геопространственных систем индексации (сжатие) [7] и визуализация индекса H3 от Uber [8]. Изображения адаптированы с разрешения авторов. Copyright (c) CARTO 2023. Copyright (c) Uber 2018. Мотивация для использования геопространственных систем индексации (сжатие) [7] и визуализация индекса H3 от Uber [8]. Изображения адаптированы с разрешения авторов. Copyright (c) CARTO 2023. Copyright (c) Uber 2018.](https://habrastorage.org/r/w780/getpro/habr/upload_files/265/fe0/3f4/265fe03f440f97fe760cc4588a63c4cf.png)
В Databricks система индексов H3 также оптимизирована для использования с движком Spark SQL, поэтому можно писать запросы вроде этого соединения «точка в полигоне» в виде аппроксимаций в H3: сначала точки и полигоны преобразуются в индексы H3 на нужном уровне детализации (разрешение 7, что соответствует площади примерно 5 км²), а затем поля с индексами H3 используются как ключи для соединения:
WITH locations_h3 AS (
SELECT
id,
lat,
lon,
h3_pointash3(
CONCAT('POINT(', lon, ' ', lat, ')'),
7
) AS h3_index
FROM locations
),
regions_h3 AS (
SELECT
name,
explode(
h3_polyfillash3(
wkt,
7
)
) AS h3_index
FROM regions
)
SELECT
l.id AS point_id,
r.name AS region_name,
l.lat,
l.lon,
r.h3_index,
h3_boundaryaswkt(r.h3_index) AS h3_polygon_wkt
FROM locations_h3 l
JOIN regions_h3 r
ON l.h3_index = r.h3_index;
GeoPandas и Mosaic также позволяют выполнять геопространственные соединения без каких-либо аппроксимаций, если это требуется, но на практике использование H3 часто даёт достаточно точное приближение для соединений и аналитики, например при расчёте плотности. В облачной аналитической платформе можно дополнительно использовать API, чтобы подмешивать данные о трафике и расчёты времени в пути через такие сервисы, как Open Route Service [9], или обогащать геопространственные данные дополнительными атрибутами (например, транспортные узлы или торговые точки) с помощью инструментов вроде Overpass API для OpenStreetMap [10].
Слои представления геопространственных данных
Теперь, когда часть геопространственных запросов и агрегаций выполнена и аналитика готова к визуализации на последующих этапах, слой представления геопространственного lakehouse можно структурировать в зависимости от того, какие инструменты дальше будут потреблять карты или аналитические данные. На рисунке ниже показаны два типичных подхода.

Когда нужно отдавать данные в облачную геоинформационную систему (GIS) вроде ESRI Online или другое веб-приложение с картографическими возможностями, GeoJSON-файлы, хранящиеся в томе «золотого» (презентационного) слоя и содержащие все необходимые данные для построения карты или дашборда, могут и быть этим слоем представления. Используя тип GeoJSON FeatureCollection, можно создать вложенный JSON, содержащий несколько геометрий и связанных с ними атрибутов («объектов», features), которые могут быть точками, линейными объектами (linestring) или полигонами. Если же на следующем этапе используется инструмент построения дашбордов вроде Power BI, то предпочтительнее может быть звёздная схема, где геометрии и атрибуты моделируются как факты и измерения, чтобы максимально использовать перекрёстную фильтрацию и поддержку мер; при этом выходные данные материализуются в виде таблиц Delta в слое представления.
Архитектура платформы и интеграции
Геопространственные данные, как правило, представляют собой лишь одну часть более широкой корпоративной модели данных и портфеля аналитических и ML/AI-сценариев. Для всего этого (в идеале) требуется облачная дата-платформа с набором входящих и исходящих интеграций, которые позволяют разворачивать решения, оркестрировать процессы и реально видеть, что аналитика приносит пользу организации. На рисунке ниже показана архитектура верхнего уровня для Azure-платформы данных, с которой я работал с геопространственными данными в прошлом.

Загрузка данных выполняется с помощью различных ETL-инструментов (по возможности сам Databricks оказывается достаточным). Внутри рабочей области (или нескольких) применяется медальная схема слоёв данных: сырые данные (bronze), корпоративный слой (silver) и слой представления (gold), при этом используется иерархия Unity Catalog catalog.schema.table/volume, чтобы при необходимости создавать разделение по слоям под отдельные сценарии (особенно с точки зрения прав доступа). Когда готовые к показу результаты можно публиковать, доступны разные варианты шаринга данных, построения приложений, дашбордов и интеграции с GIS.
Например, в случае с облаком ESRI коннектор к хранилищу ADLS Gen2 внутри ESRI позволяет забирать данные, записанные во внешний том Unity Catalog (то есть GeoJSON-файлы), прямо в платформу ESRI для включения в карты и дашборды. Некоторые организации предпочитают, чтобы геопространственные результаты записывались в нижестоящие системы, такие как CRM или другие геопространственные базы данных. Курированные геопространственные данные и их агрегации также часто используются как признаки (features) для ML-моделей, и это без швов работает с геопространственными таблицами Delta. Databricks развивает различные AI-аналитические возможности, встроенные в рабочее пространство (например, AI BI Genie [11] и Agent Bricks [12]), которые позволяют обращаться к данным в Unity Catalog на английском языке, и, вероятнее всего, долгосрочное видение состоит в том, что любые геопространственные данные будут работать с этими AI-инструментами так же, как и любые другие табличные данные — только одним из вариантов визуализации в этом случае будут карты.
В заключение
В конце концов, всё сводится к тому, чтобы делать классные карты, которые реально помогают принимать решения. На рисунке ниже показано несколько примеров результатов геопространственной аналитики, которые я делал за последние несколько лет. В основе геопространственной аналитики лежат ответы на вопросы вроде: где концентрируются люди, события или активы; сколько обычно занимает путь из точки А в точку Б; как выглядит «ландшафт» с точки зрения распределения какого-то важного признака (это могут быть ареалы обитания, уровень неблагополучия или какой-то фактор риска). Всё это важные вещи для стратегического планирования (например, где разместить пожарную часть), понимания своей клиентской базы (например, кто находится в радиусе 30 минут от моего объекта) или для оперативной поддержки принятия решений (например, какие локации именно в эту пятницу, скорее всего, потребуют дополнительной мощности).

a) анализ времени в пути;
b) поиск «горячих точек» с помощью H3;
c) кластеризация «горячих точек» с помощью методов машинного обучения. Иллюстрация автора.
Если после сборки гео-lakehouse у вас остаётся ощущение, что «данные вроде лежат правильно, но ценность всё ещё не доезжает», обычно причина не в WKT и не в слоях. Чаще болит другое: как провести события через платформу без зоопарка костылей, как выдержать масштаб аналитики, и как упаковать результат так, чтобы им реально пользовались. Разберем это и не только на бесплатных демо-уроках:
16 декабря 20:00 — Потоковые приложения с использованием Apache Kafka: от событий к реальному времени. Записаться
18 декабря 19:00 — Базовые принципы шардирования и репликации в ClickHouse. Записаться
24 декабря 20:00 — Строим простой дашборд в Tableau. Записаться
Хотите систематизировать знания в области подготовки и анализа данных и выйти на новый профессиональный уровень? Обратите внимание на курс Data Warehouse Analyst. Advanced.
filippov70
А вы не используете пространственный Spark - Apache Sedona? https://sedona.apache.org