Руководство по созданию SVG карт на основе данных сервиса Natural Earth

Добавлено 19 октября 2015 в 22:33

Интерактивные карты – это отличный способ предоставить географические данные пользователям вашего сайта. Одним из популярных вариантов реализации подобного являются такие сервисы, как Google Maps и Open Street Maps, которые преуспели в визуализации данных до уровня улиц. Тем не менее, для мелкомасштабных карт наиболее подходящим вариантом являются карты в формате SVG. Они легки, полностью настраиваемы и не обременены никакими ограничениями лицензирования.

Можно найти ряд SVG карт, выпущенных в рамках разрешительных лицензий в Википедии. К сожалению, того, что вы в конечном итоге найдете, может вам не хватить. Необходимая вам карта может не существовать, может быть устаревшей (например, из-за изменения границ) или может быть недостаточно хорошо отформатирована для использования на вашем сайте. Данная статья объяснит, как создавать ваши собственные SVG карты, используя данные сервиса Natural Earth и open-source инструменты. После чего вы сможете создавать SVG карты для любого региона мира, используя любую проекцию и любое разрешение. В качестве примера мы создадим SVG карту мира.

Нам будет необходимо выполнить следующее:

  • скачать географические данные с Natural Earth data;
  • просмотреть и отредактировать данные, используя QGIS;
  • конвертировать географические данные в SVG, используя Kartograph.py.

Получение географических данных

Для начала, нам необходимы географические данные о границах стран. Эти данные доступны на Natural Earth. Natural Earth создан добровольцами при поддержке Северо-Американского картографического информационного общества (NACIS, North American Cartographic Information Society). Данный сервис специализируется на мелкомасштабных картах, которые хорошо подходят для интернета. Это означает, что карты будут отлично смотреться на уровне стран и провинций, но с недостаточно большим разрешением, чтобы показать окрестности города. Natural Earth выпускает свои карты в общественное достояние.

Чтобы посмотреть все карты, доступные для скачивания, посетите страницу загрузок Natural Earth.

Многие границы в мире горячо оспариваются. Политика Natural Earth заключается в рисовании границ в зависимости от того, кто контролирует ситуацию на местах. Мы в первую очередь будем работать с мелкомасштабной политической картой, которая содержит все 247 стран мира, и из которой удалены границы, которые проходят через озера. Вы можете скачать её в zip архиве (186 Кб).

Данные, которые вы скачали, сохранены в формате shape-файла (.shp). Shape-файл – это открытый стандарт векторного формата геопространственных данных, созданный Esri. Shape-файл сопровождается дополнительными файлами с расширениями .dbf, .prj и .shx. Вместе эти файлы содержат векторную геометрию, атрибуты (имя, id и т.д.) и геопространственные данные для каждой страны. Для простоты, когда люди ссылаются на shape-файл, они на самом деле имеют в виду эту группу файлов.

Просмотр географических данных

Чтобы увидеть данные, которые мы только что скачали, нам необходимо воспользоваться программным обеспечением GIS (геоинформационных систем). QGIS – это открытое GIS ПО, работающее под Linux, Mac OS X и Windows. Скачать ПО с QGIS. Данное руководство будет использовать QGIS 2.8.2 Wien.

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

Для начала, мы добавим наш shape-файл в наш проект как векторный слой:

  • выберите Слой (Layer) → Добавить слой (Add Layer) → Добавить векторный слой (Add Vector Layer);
  • выберите и откройте файл ne_110m_admin_0_countries_lakes.shp;
  • карта должна появиться в окне (цвет может отличаться от вашего).
The world map vector layer
Векторный слой карты мира

Обратите внимание, что ne_110m_admin_0_countries_lakes.shp был добавлен в диалоговое окно Слои.

the new layer
Новый слой

Слои в QGIS похожи на слои, которые вы можете обнаружить в таких графических редакторах, как Photoshop или GIMP. Вы должны выбрать слой перед тем, как сможете работать на нём. Если на протяжении данного руководства вы обнаружите, то программа работает неправильно, вы вероятно забыли выбрать текущий слой.

Также возможно скрыть слои, сняв флажок. Это позволяет добавить несколько shape-файлов в ваш проект и просматривать их по отдельности.

После добавления векторного слоя было бы неплохо сохранить вашу работу: Проекты (Project) → Сохранить (Save).

Каждая страна содержит список атрибутов. Вы можете посмотреть эти атрибуты в таблице: Слой (Layer) → Открыть таблицу атрибутов (Open Attribute Table).

country attribute table
Таблица атрибутов стран.

Данные Natural Earth содержат огромное количество информации о каждой стране. Для однозначной идентификации стран мы будем использовать двухбуквенные ISO коды, которые хранятся в переменной iso_a2. Также мы будем использовать название стран (name), чтобы маркировать страны в нашем SVG файле. Не стесняйтесь исследовать таблицу, чтобы понять смысл данных. Закройте таблицу, когда закончите.

Редактирование географических данных

(вы можете пропустить этот раздел, если довольны данными, предоставляемыми Natural Earth по умолчанию)

Использование QGIS позволяет редактировать отдельные географические фигуры. Возможно вам не нужно перерисовывать границы, но вы можете разделить страну на части.

Каждая фигура в нашем shape-файле соответствует объекту в QGIS. Чтобы выбрать объект, выберите Вид (View) → Выделить (Select) → Выделить объект(ы) (Select Feature(s)), а затем кликните по вашей цели. Весь объект должен стать желтым. Например, так будет выглядеть Франция, когда вы кликните по ней:

France is selected and highlighted
Франция выделена и подсвечена.

Обратите внимание, что Франция включает в себя и Французскую Гвиану в Южной Америке. Это потому что Французская Гвиана является заморскими департаментом и регионом Франции (Французская Гвиана в Википедии). Тем не менее, Французская Гвиана имеет свой уникальный ISO код, и для многих приложений это означает, что её необходимо отображать как отдельный самостоятельный объект.

Разделение Франции на два отдельных объекта – это простой процесс, требующий выполнения нескольких шагов:

  1. установить QGIS плагин Digitizing Tools:
    • Модули (Plugins) → Управление модулями (Manage and Install Plugins);
    • найти Digitizing Tools;
    • выбрать Digitizing Tools;
    • Установить модуль (Install Plugin);
  2. показать инструменты редактирования на панели инструментов: Вид (View) → Панели инструментов (Toolbars) → Дополнительные функции оцифровки (Advanced Digitizing) и Вид (View) → Панели инструментов (Toolbars) → Digitizing Tools;
  3. перевести карту в режим редактирования: Слой (Layer) → Режим редактирования (Toggle Editing);
  4. выделить Францию: Вид (View) → Выделить (Select) → Выделить объект(ы) (Select Feature(s));
  5. кликнуть на Франции на изображении карты;
  6. выбрать Split selected multi-part features to single part на панели инструментов
    split france

    Это разделит все части Франции на отдельные объекты.
  7. вернуть остальные части Франции целиком:
    • выделите материковую часть Франции и остров Корсика. Для выбора нескольких объектов удерживайте Ctrl (Cmd на Mac);
    • объедините материковую часть Франции и остров Корсика (Правка (Edit) → Объединить выделенные объекты (Merge Selected Features)) – вы будете предупреждены, что атрибуты объектов также будут объединены. Нажмите OK;
  8. отредактировать атрибуты Французской Гвианы:
    • Вид (View) → Определить объекты (Identify Features);
    • кликнуть на Французской Гвиане. Это отобразит атрибуты Французской Гвианы в диалоге Результат определения, которые на текущий момент содержат атрибуты Франции. Мы должны заменить их атрибутами Французской Гвианы. Нажмите на кнопку Открыть форму объекта (ред.) Edit feature form, как показано на скриншоте. Замените ISO код на "GF" и name на "French Guiana";
      Replacing French Guiana’s attributes
      Замена атрибутов Французской Гвианы
  9. сохранить свои изменения: Слой (Layer) → Сохранить правки (Save Layer Edits).

Вот и всё! Французская Гвиана теперь отдельный объект, и мы задали ему уникальные атрибуты. Чтобы узнать больше о редактировании, просмотрите документацию QGIS.

Создание SVG файлов с Kartograph.py

Kartograph.py – это легкая библиотека на Python, которая сконвертирует наш shape-файл в дружественный для веб-использования SVG файл. Она была создана Грегором Айшем (Gregor Aisch), графическим редактором New York Times, и доступна под лицензией AGPL.

Чтобы установить Kartograph.py, следуйте инструкциям по установке. Этот процесс потребует установки ряда зависимостей. Если вы не готовы к такому большому количеству установок, то можете установить Kartograph.py на виртуальную машину. Или можете просто скачать конечный SVG файл, показанный в виде изображений в данной статье. Данное руководство создано при использовании Kartograph.py, установленного на Ubuntu 14.04 LTS.

Kartograph управляется из командной строки и требует наличия конфигурационного файла в формате JSON. Назовите этот файл config.json и поместите его в каталог с shape-файлом. Данный файл должен содержать свойства слоев со словарем слоев, которые мы хотим конвертировать, и положение каждого слоя shape-файла. Чтобы преобразовать ne_110m_admin_0_countries_lakes.shp, мы можем использовать следующий config.json:

{
  "layers": {
    "countries": {
      "src": "ne_110m_admin_0_countries_lakes.shp"
    }
  }
}

Затем выполните в консоли следующую комнду Kartograph:

kartograph config.json -o world_basic.svg

Kartograph создаст world_basic.svg в текущем каталоге. Если вы откроете этот файл в современном браузере, то увидите карту мира.

See the Pen OyOexa by RadioProg (@radioprog) on CodePen.

Изменение проекции карты

Вы можете заметить, что данная карта выглядит несколько иначе, чем карта в QGIS. Есть целый ряд различных способов спроецировать нашу трехмерную Землю на двухмерное пространство. По умолчанию Kartograph использует проекцию Робинсона, красиво выглядящую проекцию, обычно используемую для карт мира. Однако вы можете предпочесть работать с проекцией Меркатора (используется в Google Maps), которая проецирует широту и долготу в качестве прямых линий. Чтобы сделать это, добавьте объект proj после объекта layers в файл config.json:

"proj": {
  "id":"mercator"
}

Уменьшение размера файла

Часто созданный SVG файл может быть слишком большим для практичного использования в веб-приложении. Kartograph включается в себя алгоритм упрощения Висвалингам–Уайатта, который позволяет резко уменьшить размер файла при незначительных визуальных изменениях границ стран. Наш файл уже достаточно мал (231 Кб), то мы можем упростить его еще, добавив свойство simplify в конец объекта countries:

"simplify": 1

Чем выше значение simplify, тем сильнее границы стран будут упрощены, и тем меньше будет выходной файл.

Фильтрация объектов

По умолчанию карта будет включать в себя все объекты, представленные в shape-файле. Но вы можете исключить определенные объекты из SVG файла. Например, мы можем захотеть удалить Антарктиду, так как она не имеет отношения к нашей задаче. Kartograph включает в себя инструмент фильтрации, позволяющий отсеять объекты на основе их атрибутов. Мы можем исключить Антарктиду, используя её ISO код. Чтобы сделать это, добавьте свойство filter к слою countries:

"filter": ["iso_a2", "not in", ["AQ"]],

Сохранение данных внутри SVG файла

В завершение, мы хотим, чтобы наша SVG карта включала в себя атрибуты данных с ISO кодом и названием каждой страны. Это позволит идентифицировать SVG элементы в браузере. Чтобы сделать это, добавьте свойство attributes к слою countries:

"attributes": {
  "id": "iso_a2", 
  "name": "name"
},

Собираем всё вместе

После внесения всех изменений config.json будет выглядеть следующим образом:

{
  "layers": {
    "countries": { 
      "src": "ne_110m_admin_0_countries_lakes.shp",
      "filter": ["iso_a2", "not in", ["AQ"]],
      "attributes": {
        "id": "iso_a2",
        "name": "name"
      },
      "simplify": "1"
    }
  },
  "proj": {
    "id": "mercator"
  }
}

Выполните ту же команду Kartograph, что и ранее (с новым именем SVG файла):

kartograph config.json -o world.svg

Kartograph создаст новую карту world.svg, которая меньше по размеру и выглядит немного иначе:

See the Pen yYpBQZ by RadioProg (@radioprog) on CodePen.

Если вы откроете этот файл в текстовом редакторе, то увидите, что каждый <path> теперь содержит идентифицирующую информацию в следующей форме:

data-id="US" data-name="United States" id="US"

Данное введение лишь слегка касается того, что возможно с Kartograph. Вы можете использовать несколько слоев, объединять объекты вместе, кадрировать карту, используя широту и долготу. Вы можете узнать о этих и многих других возможностях из документации Kartograph.py.

Добавление SVG карты на сайт

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

<img src="world.svg" alt="World Map">

Однако встраивание карты подобным способом затрудняет возможности по изменению внешнего вида карты и приданию ей интерактивности. Простой способ обеспечить возможность применения CSS и JavaScript к карте – встроить SVG файл в HTML код. Просто откройте world.svg в текстовом редакторе, скопируйте весь элемент <svg>, и вставьте его непосредственно в код страницы.

Элемент <svg> содержит отдельный <path> для каждой страны. Чтобы изменить стиль карты, просто примените CSS ко всем елементам <path>. Используйте свойства fill и stroke, чтобы изменить для каждой страны цвет и границу соответственно. Например, мы можем сделать все страны светло-серыми и добавить эффект наведения:

path {fill: lightgray; stroke: white;}
path:hover {fill: gray;}

Аналогичным образом мы можем использовать JavaScript для задания обработчиков событий. Следующий код будет выводить модальное окно с названием страны при клике на неё:

<script>
 // <![CDATA[
  var countryElements = document.getElementById('countries').childNodes;
  var countryCount = countryElements.length;
  for (var i = 0; i < countryCount; i++) {
   countryElements[i].onclick = function() {
    alert('You clicked on ' + this.getAttribute('data-name'));
   }
  }
 // ]]>
</script> 

Он должен быть помещен после элемента <svg>, прямо перед закрытием тега <body>. Ваш конечный HTML файл должен выглядеть подобным образом:

 скачать пример интерактивной карты мира на веб странице

See the Pen OyzJOa by RadioProg (@radioprog) on CodePen.

Надеюсь, этот простой пример показывает, как можно легко манипулировать вашей SVG картой с JavaScript и CSS. Для более сложной интерактивности (например, анимация SVG путей), обратите внимание на такую SVG JavaScript библиотеку, как Snap.js.

Заключение

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

Теги

ECMAScriptJavaScriptSVGГеографические карты

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.