Как стать автором
Обновить
415.66
Ozon Tech
Стремимся делать лучший e-commerce в России

Анализируем данные с помощью визуализации: рисуем поверх Google Maps

Время на прочтение6 мин
Количество просмотров9K

Привет, я Катя, системный аналитик в Ozon. Одна из первых задач, которую мне поручили здесь — проверить качество географических данных. Формально эта задача больше относится к анализу данных, чем к системному анализу. Но меня она очень заинтересовала, ведь требовался не только анализ, но и исследование и, по возможности, реализация решения, а для меня это самое интересное в работе. 

Впереди меня ждала RnD-задача с исследованием картографических форматов, рисованием поверх Google Maps и реализацией скрипта на Python. Как я боролась с визуализацией картографических данных, расскажу в этой статье.

Как работает определение населённого пункта

У нас в Ozon есть сервис, который по переданной координате определяет населённый пункт. Это своего рода обратное геокодирование. 

Время от времени от коллег из поддержки нам прилетали сообщения о том, что сервис некорректно определяет населённый пункт. Например, на картах Яндекса координаты соответствуют Алматы, а наш сервис считает, что это Баганашыл. Забегая вперед, покажу, как выглядели данные по Алматы в нашем сервисе.

Пришло время проверить корректность географических данных, хранящихся в нашей системе.

Данные для нашего сервиса мы храним в PostrgreSQL с расширением PostGIS, которое позволяет работать с географическими объектами. Для определения населенного пункта нужны: его название, координата центра и геометрия, обозначающая его границы (полигон или мультиполигон).

Населённый пункт мы определяем по вхождению переданной координаты в геометрию. Если не нашли, то ищем ближайшую координату центра.

Определение населённого пункта по вхождению точки в геометрию является самым точным методом, но есть важная деталь: данные должны быть корректными. В нашем случае именно корректность данных по полигонам стала проблемой. Эти данные копились в системе в течение всей её жизни. Что-то вносили вручную, что-то унаследовано из других систем,

Раз речь о картах — наглядной информации, то для проверки корректности данных мы решили их визуализировать. Задачей было нанести полигоны и координаты центров городов поверх реальной карты и визуально оценить, насколько всё хорошо или плохо.

Как импортировать географические данные

У нашего сервиса нет пользовательского интерфейса, поэтому для визуализации географических данных нам нужен был сторонний инструмент с возможностью импорта данных.

Такая возможность есть у обоих «главных» картографических сервисов — Google Maps и Яндекс.Карт. 

 К слову, лично мне больше понравился импорт Google Maps: интуитивно понятнее, подробнее сообщает об ошибках, штатно позволяет загружать координаты точек без формирования CSV-файла по жёсткому шаблону.

 И Google Maps, и Яндекс.Карты позволяют с помощью CSV-файла отобразить на карте объекты по их координатам. Однако, чтобы загрузить более сложную геометрию (полигоны, мультиполигоны, линии), нужно иметь файл специфического картографического формата. 

 Google Maps поддерживает импорт в следующих форматах:

  • CSV и XLSX — для отображения координат точек, 

  • GPX — для маршрутов, 

  • KML — для любых географических объектов. 

 У Яндекс.Карт похожий список. Разница лишь в том, что нет GPX, но есть GeoJSON, который по назначению аналогичен KML. 

 Мой выбор пал на формат KML. 

Keyhole Markup Language

Основная причина, по которой я выбрала KML для импорта данных на карты, заключалась в том, что этот формат поддерживают и Google, и Яндекс. Правда, как позже показала практика, бывают файлы с полигонами, которые отображаются на Google Maps, но не видны на Яндекс.Картах (но тогда мне ещё только предстояло это выяснить). 

Ещё KML — это язык разметки на основе XML, так что я подумала, что сформировать такой файл будет не очень сложно.

У KML много возможностей — он даже позволяет отрисовывать 3D-объекты. Для решения моей задачи оказалось достаточно пяти элементов:

  1. Placemark — объект, позволяющий задавать геометрию (от координаты точки до мультиполигонов).

  2. Multigeometry — контейнер для нескольких геометрических примитивов, связанных с одним и тем же географическим объектом (например, для координаты центра и полигона).

  3. Polygon — многоугольник области; может дополнительно содержать внутреннюю вырезанную область. Мультиполигоны для отображения разбиваются на полигоны.

  4. Point — географическое местоположение, определяемое долготой и широтой. Координаты следуют в таком порядке: сначала долгота, потом широта.

  5. Style — стиль представления геометрии (например, цвет).

Пример структуры файла для отображения одного объекта, состоящего из точки и полигона:

<Placemark>
      <description>Описание объекта</description>
      <name>Название объекта</name>
      <!-- Задаём стиль для полигона --> 
      <Style> 
        <PolyStyle>
          <!-- Первые два символа цвета отвечают за прозрачность, последующие шесть — за цвет в формате RGB -->
          <color>4DA0753A</color>
          <fill>1</fill>
          <outline>1</outline>
        </PolyStyle>
      </Style>
      <MultiGeometry>
        <Point>
          <!-- Первым следует значение долготы, вторым — широты --> 
          <coordinates>80.786232, 45.748985</coordinates>
        </Point>
        <Polygon>
          <!-- Задаём внешнюю границу полигона --> 
          <outerBoundaryIs>
            <LinearRing>
              <!-- Точки разделяются между собой пробелом, долгота и широта — запятой; первой указывается долгота, второй — широта --> 
              <coordinates>80.7643897, 45.7327094 80.7777888, 45.7297088 80.7831002, 45.7416147 80.8001875, 45.7445317 80.8058787, 45.7502633 80.7931381, 45.758115 80.7738655, 45.7542795 80.7643897, 45.7327094</coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
      </MultiGeometry>
    </Placemark>

Финишная прямая: от KML к отображению своих объектов на карте 

Файл из тысяч элементов не хочется формировать вручную. С генерацией KML-файлов мне помогла Python-библиотека pyKML.

Я написала небольшой скрипт: на вход он принимает XLSX-файл с данными о географических объектах. Структура файла – четыре колонки: наименование, описание, координата точки, геометрия в текстовом формате WKT (может быть пустой). На выходе формируется KML-файл, который можно использовать для отображения своих объектов на картах. 

На всякий случай предупрежу: у Google Maps есть ограничение по количеству импортируемых объектов в 2000 штук. Если нужно отобразить больше, то придётся сделать несколько файлов.

Помните, как выглядел Алматы на карте в начале статьи? Несколько точек и только одна из них принадлежала непосредственно городу Алматы, остальные являлись районами, улицами, парками, в общем, не являлись населенными пунктами. Имея дело с такими данными, наш сервис в большинстве случаев ошибался (у Алматы не было полигона, поэтому алгоритм находил не сам город, а ближайшую точку, которая по факту городом не является).

А вот так Алматы преобразился после обновления данных. Теперь есть полигон и можно быть уверенными, что всё множество точек, входящих в границы города, будет определяться правильно. Такая визуализация помогает увидеть проблемные места и убедиться в корректности данных после обновления. 

Когда всё-таки звать разработчиков для помощи 

Google Maps предоставляет отличные возможности для отображения географических данных без каких-либо серьёзных дополнительных манипуляций. Для визуализации в виде «было — стало» сервис подходит отлично, на мой взгляд: можно наглядно убедиться в корректности географических данных. 

Когда может не подойти такой подход, и потребуется привлекать тяжёлую артиллерию— разработчиков? Предположим, у вас есть данные о движении грозовых фронтов, и вы хотите показывать их пользователю в режиме реального времени. В этом случае импорт файлов на карту вручную не подойдёт. Однако предполагаю, что формирование KML-файлов для решения этой задачи тоже может пригодиться: вы сможете встроить в своё приложение карту и отрисовывать данные уже программным способом.   

Как всегда, это история о балансе: сделать быстро или основательно, разбираться самостоятельно или обратиться за помощью, следовать инструкции или интуиции. Когда вам в следующий раз придётся делать такой выбор, надеюсь, моя история не будет вас перетягивать на одну из сторон, но напомнит: иногда вы можете больше, чем сами от себя ожидаете. 

И конечно, желаю вам качественных данных и успехов в их визуализации!

Ссылки вдогонку

Теги:
Хабы:
Всего голосов 20: ↑18 и ↓2+16
Комментарии22

Публикации

Информация

Сайт
ozon.tech
Дата регистрации
Дата основания
Численность
5 001–10 000 человек
Местоположение
Россия