В этой статье описывается достаточно простой способ построения пиксельных карт. Для построения пискельной карты необходимо преобразовать геоданные (формы материков, стран) в пиксели, то есть, разделить карту на одинаковые полигоны с заданием размеров этих полигонов. Пример такой карты есть у меня на Tableau Public. В этом примере можно переключаться на 3 вида полигонов, и есть 2 уровня грануляции данных (Normal и High). Эта карта полностью интерактивна, можно приближать и удалять карту. Под понятием пикселя на карте в дальнейшем будем понимать квадрат, который представляет часть суши на карте, То есть, мы разбиваем всю карту на квадраты и выделяем только те пиксели, которые представляют участок суши.

1. Примеры пиксельных карт и методы их построения

Надо отметить, что примеры пиксельных карт на Tableau Public есть, и большинство таких примеров строится на данных, используя метод округления широты и долготы. Вы можете посмотреть визуализацию Mark BradbourneACLED — ARMED Conflict in Africa‘ и визуализацию ‘Most Dangerous Places‘ от Mike Cisneros. Еще можно посмотреть такую карту на моей визуализации ‘Rat Sightings in Manhattan‘. Хочется отметить, что все перечисленные проекты были разработаны в рамках инициативы Makeover Monday, где можно учиться визуализации данных, смотреть как это делают другие и общаться с комьюнити.

1. Метод округления широты и долготы

Если вкратце рассмотреть как работает метод округления широты и долготы, то суть его в том, что отдельные события на карте группируются в квадраты, цветом в которых показано количество событий, то есть, получаем карту плотности событий. Это видно на скриншотах снизу, где события наблюдения крыс на Манхеттене заменяются на квадраты-пиксели. Широта и долгота при этом округляются до второго знака. Можно создавать вычисления сложнее, чем просто обычное округление для того, чтобы выбирать любой шаг изменения широты/долготы.

 

Давайте рассмотрим проблемы, которые возникают при таком методе визуализации:

  • Одна из проблем пиксельных карт, которые собираются на данных путем округления широты и долготы, в том, что не все участки на картах вы можете заполнить пикселями, а только те, для которых есть данные.
  • Другая проблема — зум карты. Если посмотреть мою визуализацию ‘Rat Sightings in Manhattan‘ и приближать/удалять карту, то размер пикселей не будет меняться, а карта при этом будет приближаться или удаляться, соответственно, такие карты не нужно делать с возможностью зума, поскольку расчет размеров пикселей будет справедлив только для одного масштабе. Именно поэтому обычно отключают возможность зума на карте.

  • Еще одна проблема — это проблема нелинейности изменения широты проекции Меркатора. Проекция Меркатора — это геопроекция, используемая в Tableau по умолчанию. Она имеет ряд недостатков, но, надо признать, что большинство пользователей работает именно с этой проекцией. Если вы применяете метод округления широты и долготы, то на проекции Меркатора вы не получите равномерную сетку пикселей по широте. Это особенно заметно на мировой карте.

 

2. Метод импортирования данных из файлов изображений формата SVG

Также можно получать визуализации пиксельных карт экспортом координат из SVG файлов. Я так делал в визуализации ‘USA Pixel Map‘. Здесь проблема в том, что количество таких файлов ограничено, поскольку их обычно создают дизайнеры. Поэтому пиксельную карту произвольной страны найти довольно сложно, при этом, карты не всегда в проекции Меркатора. Кроме этого, в SVG формате данные хранятся не как широта и долгота, а как координаты пикселей на декартовой плоскости (1,1; 12,4 и т.п.), то есть, на геослой в Tableau без преобразования данных нельзя корректно наложить.

 

3. Ручной метод рисования

Еще можно делать такие карты вручную, но это долго. Я это делал в визуализации ‘How America uses its Land‘. И здесь было потрачено много часов на ручной труд.

В методе, описываемом в этой статье, недостатки, перечисленные выше, устраняются. Давайте перейдем непосредственно к подготовке данных.

2. Подготовка данных

Для того, чтобы из стандартной карты сделать пиксельную, нам нужен алгоритм преобразования геоданных в пиксели. Подобные алгоритмы есть в геопакетах таких как QGIS, либо их можно реализовать на языках программирования. Но в этой статье я хочу привести самый простой способ генерации таких карт при помощи инструмента Pixel Map Generator. Его преимущество в том, что вы можете генерировать пиксельные карты в разных геопроекциях, выбирать карты отдельных стран с разбивкой на области, выбирать в качестве пикселей квадраты, ромбы, шестиугольники, а также выбирать размеры пикселей.

Внимание: лицензия использования этого инструмента подразумевает его упоминание и ссылку на https://pixelmap.amcharts.com. Либо нужно приобретать коммерческую лицензию.

Сам генератор работает просто — нужно выбрать опции генерации карты и нажать ‘Generate Pixel Map’. После этого нужно собрать данные для загрузки в Tableau. Для этого нужно скачать данные в формате HTML.

Я не буду использовать Tableau Desktop далее, а буду все разрабатывать в Tableau Public, чтобы расширить аудиторию и показать, что вы можете создавать хороший визуализации в Tableau Public. Клиент Tableau Public имеет ограниченное количество подключаемых источников данных, в числе которых есть формат JSON.

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

Я сформировал карту мира и сохранил данные в файле World_Map.json

3. Подключение к данным и визуализация

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

Теперь можно строить пиксельную карту. Поле title в датасете — это название страны, а images Index — это id каждого пикселя. В качестве Marks выберем квадраты.

Заметим, что при приближении карты размеры квадратов не меняются, поэтому появляются промежутки между ними.

Нам эти промежутки не нужны, и для того, чтобы избавиться от них, нужно для каждой вершины квадрата задать географические координаты. Квадрат — это полигон с количеством вершин = 4. Добавим в датасет в UNION еще 3 таблицы датасета. При добавлении таблиц в UNION, появится поле Table Name. Каждая из таблиц будет отвечать за одну вершину квадрата.

 

Теперь создадим два новых вычисления Lat и Long, описывающие координаты вершин каждого квадрата, а также числовой параметр Scale, который будет отвечать за размер квадратов. По сути, мы рисуем квадрат на декартовой плоскости с центром в точке (0,0), где Lat — это координаты по оси Y, а Long — координаты по оси X.

Lat

[latitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN [Scale]
WHEN ‘2’ THEN [Scale]
WHEN ‘3’ THEN —[Scale]
WHEN ‘n’ THEN —[Scale]
END
)

Long

[longitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN —[Scale]
WHEN ‘2’ THEN [Scale]
WHEN ‘3’ THEN [Scale]
WHEN ‘n’ THEN —[Scale]
END
)

Для этих вычислений нужно установить Geographic Role как latitude и longitude соответственно. После этого можно построить пиксельную карту, где в качестве Marks выбираем полигоны, а в Path помещаем поле Table Name — оно будет задавать очередность обхода вершин полигона.

Внимание: когда вы рисуете что-то при помощи пилюль с Geographic Role: Latitude и Longitude, у вас Tableau создает несколько слоёв карты (базовый слой, границы регионов, дороги и т.д.). Ненужные слои лучше отключить (например, дороги и границы областей), чтобы карта работала быстрее.

Обратите внимание, что ближе к полюсам квадраты начинают вытягиваться и превращаются в прямоугольники. Это происходит из-за того, что Tableau использует проекцию Меркатора. Чтобы компенсировать этот эффект растягивания, широту надо умножить на косинус угла широты, поскольку планета Земля имеет форму шара. 

Таким образом, вычисление Lat примет вид:

Lat

[latitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN [Scale]
WHEN ‘2’ THEN [Scale]
WHEN ‘3’ THEN —[Scale]
WHEN ‘n’ THEN —[Scale]
END
)
*COS(RADIANS([latitude]))

После этого карта примет вид:

Всё! Пиксельная карта готова! Можно приближать и удалять карту, квадраты будут менять размеры в соответствии с зумом. Дальше можно кастомизировать эту карту по своему вкусу.

4. Кастомные полигоны для пиксельных карт

Выше мы рассмотрели вариант, когда в качестве пикселей используются квадраты. Но можно делать другие полигоны, самое главное — корректно описать вычисления.

В моей визуализации World Pixel Map можно переключаться на гексагоны и ромбы. Для этих полигонов вычисления Lat и Long будут другими.

Для ромбов:

Lat

[latitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN 0
WHEN ‘2’ THEN [Scale]
WHEN ‘3’ THEN 0
WHEN ‘n’ THEN —[Scale]
END
)
*COS(RADIANS([latitude]))

Long

[longitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN —[Scale]
WHEN ‘2’ THEN 0
WHEN ‘3’ THEN [Scale]
WHEN ‘n’ THEN 0
END
)

Для гексагонов надо объединить в UNION 6 таблиц:

Lat

[latitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN 0
WHEN ‘2’ THEN [Scale]*COS(RADIANS(60))
WHEN ‘3’ THEN [Scale]+[Scale]*COS(RADIANS(60))
WHEN ‘4’ THEN [Scale]+2*[Scale]*COS(RADIANS(60))
WHEN ‘5’ THEN [Scale]+[Scale]*COS(RADIANS(60))
WHEN ‘n’ THEN [Scale]*COS(RADIANS(60))
END

[Scale]*COS(RADIANS(60))-[Scale]/2
)
*COS(RADIANS([latitude]))

Long

[longitude]+
(
CASE RIGHT([Table Name],1)
WHEN ‘1’ THEN 0
WHEN ‘2’ THEN [Scale]*SIN(RADIANS(60))
WHEN ‘3’ THEN [Scale]*SIN(RADIANS(60))
WHEN ‘4’ THEN 0
WHEN ‘5’ THEN —[Scale]*SIN(RADIANS(60))
WHEN ‘n’ THEN —[Scale]*SIN(RADIANS(60))
END
)

С гексагонами карта будет выглядеть так:

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

5. Объединение пиксельной карты с данными

Выше мы строили только пиксельные карты, которые описывают геометрию стран и континентов, но на них не накладываются реальные данные. Поэтому мы можем объединить пиксели на карте и данные.

Объединять данные лучше либо через Relationships либо через Blend. Можно и через JOIN, но надо помнить, что при построении полигонов (объединении таблиц) вы увеличили количество строк в несколько раз. 

Рассмотрим два случая объединения данных:

1. Данные континентов, стран, областей

Этот случай, при котором одной стране соответствует один показатель. Ниже приведен скриншот случая, когда пиксельная карта объединена с данными ВВП стран за 2020 год, и в качестве цвета используется значение ВВП. То есть, каждая страна закрашивается своим цветом шкалы Continious для метрики ВВП.

2.  Плотность событий на территориях стран, областей

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

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

Давайте посмотрим на дорожные происшествия в Великобритании в 2012-2014 годах. Ниже первая картинка — это ДТП с реальными значениями широты и долготы. Вторая картинка — количество ДТП в рамках каждого пикселя, где данные получены путем округления широты и долготы до первого знака. Третья картинка — пиксельная карта Великобритании.

Нам нужно перенести количество ДТП со второй картинки на пиксельную карту. Если вы внимательно посмотрите на второе изображение, то видно, что, по мере приближения к Северному полюсу, увеличивается расстояние между пикселями. Это обусловлено тем, что в проекции Меркатора широта меняется нелинейно. Таким образом, получаем, что на пиксельной карте 3 фактическая площадь каждого пикселя увеличивается по мере возрастания значений широты.

Внимание: в этом и заключается проблема: если мы сгруппируем события на пиксельной карте, то получим некорректную картину данных из-за того, что используем проекцию Меркатора.

На самом же деле можно перенести данные на пиксельную карту. Нужно поставить в соответствие (JOIN, Relationships, Blending) каждому пикселю на пиксельной карте количество событий и закрасить пиксели градиентной шкалой. Это не самая простая задача, но она реализуема.

3.  Пиксельные карты с данными площади

Есть варианты, когда пиксели закрашиваются дискретно, в зависимости от категорий использования площади. Например, карта использования земель в США показывает преимущественные категории использования земель в каждом пикселе.

Визуализация от Alex Waleczek показывает аналогичное распределение земель в Новой Зеландии.

 

4.  Пиксельные карты высот или глубин

В статье ‘Dirks LEGO World Map‘ рассказывается о процессе создание пиксельной карты мира из кубиков LEGO

Alex Waleczek написал интересную статью про создание карты высот Новой Зеландии. Ниже показана пиксельная карта высот Новой Зеландии, которую он сделал.

Подготовку данных для таких карт можно делать в специализированных геопакетов, например, QGIS, либо с помощью языков программирования.

Заключение

Пиксельные карты — это экзотическая визуализация, но она встречается в инфографике, аналитических статьях таких изданий как Bloomberg. 

Преимущество таких карт перед обычными Choroplet Maps — это то, что вы можете видеть небольшие области (острова) в виде пикселя или двух. Например, государство Maльта на стандартной карте плохо заметно, а пиксель выделяет его на карте. Недостатками таких карт можно считать то, что небольшие государства, такие как Ватикан, могут потеряться, поскольку Италия займет пиксель просто потому, что площадь Италии на пикселе больше.

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