В течение нескольких лет я работал над картами, которые используются в русском и других языковых разделах Википедии. Всего мной было создано более 300 карт. Я не являюсь профессиональным картографом, и не имею специального образования в этой области. Видимо, мне просто нравилось делать карты :)
В рамках этой статьи я хочу поделиться опытом создания карт для Википедии, с фокусом на позиционных картах.
Позиционные карты
Все графические материалы для Википедии, опубликованные под свободными лицензиями, размещаются на Викискладе, это позволяет использовать их в любых проектах Wikimedia и во всех языковых разделах Википедии.
Среди всех типов карт в Википедии особо выделяются так называемые «позиционные карты». Особенность тут в том, что это не просто изображение карты, но изображение в известной проекции, с известными географическими координатами для углов. Для такой карты, в каждом языковом разделе где она используется, создаётся специальный шаблон, описывающий эти метаданные. Имея такой шаблон, мы можем применять его на любой странице, размещая поверх карты маркеры для интересующих нас объектов. Координаты объектов описываются в виде географических координат, формулы в шаблонах рассчитывают куда именно поставить маркер. Так, например, на страницу о регионе можно вставить карту этого региона и отметить на ней районные центры и крупные города.
Пример использования позиционной карты в карточке статьи об острове Пеббл. Красный маркер и надпись автоматически размещены на месте объекта поверх изображения карты.
Позиционные карты используются во всех статьях об административных единицах: страны/районы/города/посёлки итд., а также во многих статьях о географических объектах. Часто получается так, что сразу после создания позиционной карты она применяется в 20-50 существующих статьях Википедии.
В шаблоне позиционной карты, по идее, должны использоваться сразу два рисунка карты: «контурная»/«политическая» карта, и «физическая»/«географическая» карта с теми же самыми координатами, проекцией и размерами. Контурная карта как правило векторная (SVG), физическая карта может быть векторной, но чаще всего это растр (обычно PNG).
Пример шаблона позиционной карты с двумя типами карт
Позиционных карт нужно много: они должны покрывать все уровни от мира в целом до отдельных районов, небольших островов и т.д. Кроме позиционной карты, для всех административных объектов создаётся т.н. «локатор», это карта, на которой ярким цветом подсвечен интересующий нас район (пример карты-локатора). На «верхнем» уровне (мир, страна) с позиционными картами всё относительно хорошо, но на «нижнем» (уровня районов) часто всё довольно плохо: нет позиционных карт или есть, но недостаточного качества, или выполненные в неподходящем/нестандартном стиле.
Только для РФ мы имеем 83 субъекта, если добавить к этому районы, то получим уже наверное тысячу или больше административных единиц, на каждую из которых нужна позиционная карта, включая контурную карту, физическую карту, карту-локатор… К тому же, время от времени происходят изменения вида «вышло новое постановление»: появляется юридический документ, который меняет границы административных единиц, разделяет/объединяет их и т.п. И конечно, во всех таких случаях нужно перерисовать одну или несколько позиционных карт.
В общем, я думаю вы уже поняли — карты очень нужны и их нужно много :)
Исходные данные для карт
Для позиционных карт должны использоваться изображения со свободной лицензией. Это значит, что и исходные данные для таких карт должны быть свободными.
Исходные данные для карт, которыми я пользовался:
- OpenStreetMap — основной источник векторных данных; но нужно учитывать, что данные получаются краудсорсингом, поэтому местами они плотные и качественные, местами очень неполные. Встречаются и ошибки в данных, поэтому полученные карты нужно аккуратно проверять.
- GSHHG — векторные данные в составе GMT (см. ниже); можно использовать для карт крупных масштабов, плохо подходит для мелких масштабов.
- ETOPO1 (разрешение ~1,85 км, объём ~890 МБ), ETOPO2 (разрешение 2' ~= 3,6 км) — карты высот, включая рельеф морского дна (батиметрию).
- TOPO30 (разрешение ~= 0,9 км, объём ~1800 МБ) — карта высот, включая рельеф морского дна.
- GLOBE (разрешение 30" ~= 0,9 км) — карта высот.
- SRTM (разрешение SRTM3: 3" ~= 90m) — довольно подробная карта высот, но из-за этого и довольно «увесистая» (каждый файл с данными размером 1x1 градус весит ~2,8 МБ), поэтому обычно приходится скачивать только нужные файлы. Кроме того, исходные данные SRTM имеют разрывы, которые нужно закрывать, интерполируя отсутствующие точки по соседним. Это можно сделать самому, либо использовать «void-filled» исходники, такие как SRTM-Plus. SRTM это карта высот только для суши, не содержит данных о рельефе морского дна.
Проекции
В подавляющем большинстве случаев мы работаем с проекцией которая называется «равнопромежуточная цилиндрическая». К этому же семейству проекций относится проекция Меркатора и её частный случай — «проекция Гугла» или «Web Mercator projection», которую используют все основные веб-карты. Формулы для этой проекции довольно просты, к тому же шаблоны позиционных карт уже «знают» эту проекцию.
В немногих остальных случаях придётся погуглить нужную проекцию и почитать специальную литературу, чтобы понять, как именно получаются координаты x,y из широты и долготы. Mediawiki имеет развитый механизм вычисления выражений (в том числе с тригонометрическими функциями), его можно использовать для проверки своих карт, ещё до того как вы сделаете по ним шаблон позиционной карты (примеры можно посмотреть здесь).
Инструменты для создания карт
Инструментов для создания карт (геоинформационные системы, ГИС) довольно много, в том числе бесплатных и с открытым исходным кодом. Но для того чтобы карта была открытой не обязательно использовать открытую и бесплатную систему, достаточно того чтобы исходные данные были открытыми, и того чтобы вы сами поставили на готовую карту открытую лицензию. (Но тут наверняка есть много нюансов, не берусь залезать в область авторского права, не моё :)
Для создания карт я пользовался в основном тремя программами, описанными ниже.
Maperitive
Maperitive — бесплатный, но закрытый продукт. Крайне полезен при работе с данными OpenStreetMap, работает с данными как с сайта OSM, так и с сохранёнными дампами. Позволяет выбрать стилевик и сохранить карту в формате SVG. Есть ряд готовых стилевиков и можно писать свои. Я подготовил несколько файлов стилей, и использую их для экспорта в SVG границ районов, и карт самих районов с поселениями.
Generic Mapping Tools (GMT)
Вообще, Generic Mapping Tools (GMT) это бесплатный набор утилит командной строки, предназначенный для обработки и визуализации научных данных, в том числе ряд его инструментов позволяют работать с геоданными, т.е. мы можем использовать GMT как консольную ГИС. Готовая карта (или отдельный слой для будущей карты) получается в результате последовательности вызова утилит. Обычно я пишу командный файл, в котором задаются все параметры и выполняется вызов утилит. С первого взгляда выглядит сложно, но мне как программисту такой подход кажется понятным и привычным. Кроме того, здесь обеспечивается повторяемость: чтобы создать карту снова, я всегда могу запустить скрипт ещё раз.
Пример командного файла (см. также здесь):
set PATH=C:\programs\GMT5\bin;%PATH%
set GSBIN=C:\PROGRA~1\gs\gs9.04/bin
set COORDSCUT=144.7492/157.3007/42.9694/51.3837
rem width = xmaxsvg / 150.0 * 2.54
set PAPERX=14.9352
rem height = ymaxsvg / 150.0 * 2.54
set PAPERY=16.0189333333333
grdcut.exe ETOPO1_Bed_g_gmt4.grd -R%COORDSCUT% -Gh_cor_cut.grd
grdgradient h_cor_cut.grd -Ne0.3 -A315 -M -Ghi.grd
grdimage h_cor_cut.grd -Ihi.grd -Cwiki-water-verlauf2.cpt -P -R%COORDSCUT% -JX%PAPERX%cd/%PAPERY%cd --PAPER_MEDIA=Custom_%PAPERX%cx%PAPERY%c -X0 -Y0 -K > map.eps
pscoast.exe -JX%PAPERX%cd/%PAPERY%cd -R%COORDSCUT% -Gc -P -Df --PAPER_MEDIA=Custom_%PAPERX%cx%PAPERY%c -X0 -Y0 -O -K >> map.eps
grdimage h_cor_cut.grd -Ihi.grd -Cmount.cpt -P -R%COORDSCUT% -JX%PAPERX%cd/%PAPERY%cd --PAPER_MEDIA=Custom_%PAPERX%cx%PAPERY%c -X0 -Y0 -O -K >> map.eps
pscoast.exe -JX%PAPERX%cd/%PAPERY%cd -R%COORDSCUT% -Q -P -Df --PAPER_MEDIA=Custom_%PAPERX%cx%PAPERY%c -X0 -Y0 -O -K >> map.eps
pscoast.exe -JX%PAPERX%cd/%PAPERY%cd -R%COORDSCUT% -Na -Ia/0.25p,#0978AB -W0.25,#0978AB -P -Df --PAPER_MEDIA=Custom_%PAPERX%cx%PAPERY%c -X0 -Y0 -O >> map.eps
%GSBIN%\gswin32c.exe -dSAFER -dBATCH -dNOPAUSE -dGraphicsAlphaBits=4 -sDEVICE=pngalpha -dEPSCrop -r150 -sOutputFile=Oblast_etopo.png map.eps
Результат:
В составе GMT, вместе с инструментами командной строки также поставляются и данные, этот набор называется GSHHG, карты из этих данных создаются с помощью утилиты pscoast
, входящей в GMT.
Inkscape
Inkscape — свободный и открытый векторный графический редактор, основным форматом которого является SVG.
Maperitive и GMT я обычно использую как инструменты для подготовки отдельных слоёв будущей карты. Затем полученные слои импортируются в отдельные слои в документе Inkscape, и вся завершающая работа над картой проходит уже там. Так, например, для позиционной карты нужно, чтобы район, показанный на карте, был «подсвечен» — цветом на контурной карте и затенением на физической карте. Это уже ручная работа над объектами и слоями в Inkscape.
Последним шагом по подготовке изображений карты будет сохранение SVG (для векторной карты) или экспорт PNG (для растровой).
Процесс создания карты
- Начинаю я обычно с того, что беру область будущей карты и смотрю на исходные данные, которые у меня есть для этой области. Создаю примитивную контурную карту через GMT на данных GSHHG, пробую рендерить рельеф той же области на данных ETOPO1, TOPO30, смотрю как эта область выглядит в OpenStreetMap. Бывает так, что я отказываюсь от создания карты на этом этапе, если вижу что имеющихся данных недостаточно или они плохого качества, содержат ошибки или крупные пробелы.
- Дальше, исходя из прикидочных рендеров, выбираю, на каких именно данных буду делать карту.
- Создаём отдельные слои карты. Как правило, отдельно получается слой границ (например, вектор из OSM), отдельно рисунок рельефа для суши и отдельно слой подводного рельефа (батиметрии), отдельно слой береговых линий и слой рек и водоёмов. Часто бывает так, что два растровых слоя имеют разное разрешение, и тут приходится играть с интерполяцией, чтобы вместе они смотрелись более-менее органично. Например, карта рельефа для суши берётся из ETOPO1, потому что этот участок там представлен лучше, а батиметрия взята из TOPO30, и разрешение этих двух источников различается в два раза. Тогда для меньшего разрешения делаем увеличение разрешения с интерполяцией, чтобы не возникало «квадратиков», не появлялся эффект муара и т.п.
- Используя Inkscape, собираем вместе отдельные слои карты. Выполняем необходимую ручную работу, если это нужно. Пробуем экспортировать карту в растр, внимательно рассматриваем и выявляем недочёты, исправляем и повторяем. Результатом являются файлы карты, готовые для загрузки на Викисклад.
- Загружаем файлы карты на Викисклад, выполняем там документирование. Про каждый файл должно быть написано что это за карта, какого объекта, с какими координатами и в какой проекции, какие использованы исходные данные с какими лицензиями, какими инструментами выполнена работа.
- Создаём или обновляем шаблон позиционной карты в ру-вики, проверяем его использование. Убеждаемся, что объекты встают в правильные места карты, т.е. что координаты углов карты заданы правильно, и сама карта этим координатам соответствует. После этого обновляем шаблоны для этой позиционной карты в других языковых разделах.
Заключение
На создание одной карты у меня уходило от 20-30 минут (в простых случаях, когда ряд однотипных карт районов делается как на конвейере), до 4-6 часов (в сложных случаях, когда возникали проблемы с исходными данными и нужно было делать много ручной работы). На физическую карту Канады (см. КДПВ) у меня ушло несколько дней: потребовалось подобрать проекцию, которая уже использовалась на контурной карте.
Если говорить о том «что я от этого получаю», то наверное — массу эстетического удовольствия, от того какие получаются карты.
Спасибо что дочитали, надеюсь, мой опыт вам как-нибудь пригодится :)
Комментарии (14)
DS28
13.05.2019 04:28Приветствую, коллега!
Спасибо за статью, посмотрю инструменты, которыми вы пользуетесь, может пригодятся…
Я рисовал карты в проекте графическая мастерская, но там всё зависит от запроса.
Могут быть схемы сражений, путей, трубопроводов и т.д.nzeemin Автор
13.05.2019 10:44Тематические карты я тоже рисовал. Обычно начинал с контурной карты из GMT -> в формат .eps -> конвертация в .pdf -> импорт в Inkscape, либо экспорт в SVG из Maperitive, и дальше уже нанесение тематической части карты.
DS28
13.05.2019 11:00Я брал выгрузку из QGIS — он умеет выгружать svg. Потом добавлял тематическую часть в Inkscape.
Ещё вспомнил как делал карту маршрутов из аэропорта — в этом случае готовил исходник в mapbox и наносил сверху аэропорты и маршруты, но в тот раз был нужен исходник в красивых цветах, который в википедии без надобности…
trapwalker
13.05.2019 14:25+1За GMT отдельное спасибо. Я как-то умудрился не заметить этот инструментище.
Может быть имеет смысл ещё и с графикой работать в CLI? Вообще бы здорово получилось — всё описание карты в виде скрипта.nzeemin Автор
13.05.2019 14:55Скриптом я описываю только то что делается через GMT, но тематические карты можно практически полностью делать в нём. Так например можно сделать текстовый файл с координатами маркеров и расставить их тоже через GMT. Но у этого инструмента есть свои ограничения, например, проблемы с кириллицей в шрифтах.
trapwalker
13.05.2019 16:28А какие именно проблемы? Можете сделать мне максимально простой скрипт, который демонстрирует их? Мне кажется я смогу подсказать вам как решать их систематически.
david_mz
13.05.2019 18:30Погодите, то есть _все_ карты в Википедии сделаны руками, по-одной, и руками же залиты в страницы??
nzeemin Автор
13.05.2019 19:46Если карта это рисунок, на него обычно можно нажать и увидеть кто его сделал, когда и всю историю изменений :)
Википедия также использует и OSM, со своим стилем, своим рендером и своим кешем тайлов.
Что касается «руками залиты в страницы» — это не всегда так, например, для административных единиц поддерживается информация об иерархии, шаблоны автоматически подтягивают информацию о том какие карты использовать. Получается что иногда руками, иногда автоматом.
Protos
Мне кажется или с википедией что-то не так. Разве не стоит делать вставку фрейма с open street map, в базе хранить только нужные точки и области которые стоит подсветить. И выполнять все подсветки и отображения в браузере на клиенте?
Bhudh
С Panoramio тоже когда-то делали хотлинки на других сайтах.
А теперь фото с этого сайта остались в основном в Википедии.
Всё правильно Википедия делает.
nzeemin Автор
Вы имеете в виду — карту в iframe вместо рендерёных карт? Но во-первых, карты в iframe есть и так — открываются по нажатию на географические координаты объекта. Во-вторых, рендерёная карта часто удобнее, показывает именно этот объект, или объект более высокого уровня. В общем, одно не заменяет другого.
putnik
С Википедией много всего не так, но это не тот случай. Просто в Википедии есть два уровня решения проблем: на уровне движка и на уровне контента. Описываемое в статье решение на уровне контента, и хотя генерация кучи карт может показаться не самым простым делом, это всего-лишь времязатраты, сам алгоритм прост и понятен: картинки и CSS.
Как только же мы переходим к решению на уровне движка всё становится намного сложнее.
1. Нам нужна карта, которую мы будем вставлять во фрейм. OSM напрямую с официального сайта вставлять нельзя, потому что это а) передача данных пользователей сторонней компании, б) она не предназначена для этого, и не выдержит такую нагрузку. Соответственно, нужно поднимать свой стек для генерации карт на основе OSM.
2. Так как мы делаем глобальное решение, то нам сразу же нужен картостиль, который будет адекватно смотреться на всех масштабах, а не только при показе карт.
3. Нужны механизмы для добавления объектов на эти карты при помощи вики-кода. И опять же, результат должен адекватно выглядеть и для маленьких карт в карточках, и в больших на весь экран.
4. Нам нужно взять откуда-то контур страны, который мы будем отображать на карте (логично, что тоже из OSM).
5. Не забываем, что у нас пятый по посещаемости сайт, поэтому вспоминаем про кеширование и стараемся не подгружать карты без необходимости.
И да, на текущий момент это более-менее сделано, и два года назад (для сравнения — Википедия к тому моменту существовала уже 16 лет) было активно внедрено в части разделов. Сейчас в большинстве статей карта открывается вверху по ссылке на координаты, но есть и статьи (пример), в которых это используется в карточке. Но в примере как раз хорошо видно, что карта 1) достаточно шумная, 2) не достаточно информативная в одном масштабе.
Так что, даже при том, что я как раз очень активно агитирую за использование динамических карт там, где это разумно, нужно признать, что старый механизм вставки изображений не так плох, как может показаться на первый взгляд.