ИспользуйOSM

Верни контроль над своими картами

Ручная сборка тайл-сервера (18.04 LTS)

На этой странице рассказывается, как установить и настроить все необходимое программное обеспечение для работы собственного тайл-сервера. Пошаговая инструкция написаны для Ubuntu Linux 18.04 LTS (Bionic Beaver).

Установка программного обеспечения

Тайл-сервер - это набор определенных программ и библиотек, которые взаимодействуя между собой обеспечивают генерацию тайлов и их предоставление пользователям. Как это распространено в мире OpenStreetMap, существует несколько различных конфигураций тайл-серверов, так как почти у всех инструментов есть альтернативы со своими плюсами и минусами. Данное руководство описывает запуск наиболее стандартного тайл-сервара, аналогичного тому, который используется на серверах OpenStreetMap.org.

Тайл-сервер - это пять основных компонентов: mod_tile, renderd, mapnik, osm2pgsql и база данных postgresql/postgis. Mod-tile - это модуль Apache, который проверяет наличие тайла и его актуальность. Если тайл устарел, то модуль запрашивает его обновление. Renderd - утилита, обеспечивающая формирование приоритетной очереди различных типов запросов для управления и сглаживания нагрузки от запросов на рендеринг. Mapnik - библиотека, которая собственно и генерирует (рендерит) тайлы, согласно очереди предоставленной ей Renderd.

Обратите внимание, что данная инструкция была написана и протестирована на вновь установленном сервере Ubuntu 18.04. Если у вас уже установлены другие версии некоторых программ (возможно, вы обновились с более ранней версии Ubuntu, или вы настроили загрузку некоторых PPA), то вам, возможно, потребуется внести некоторые изменения.

Для того, чтобы установить эти компоненты, необходимо сначала установить различные зависимости:

sudo apt install libboost-all-dev git-core tar unzip wget bzip2 build-essential autoconf libtool libxml2-dev libgeos-dev libgeos++-dev libpq-dev libbz2-dev libproj-dev munin-node munin libprotobuf-c0-dev protobuf-c-compiler libfreetype6-dev libtiff5-dev libicu-dev libgdal-dev libcairo-dev libcairomm-1.0-dev apache2 apache2-dev libagg-dev liblua5.2-dev ttf-unifont lua5.1 liblua5.1-dev libgeotiff-epsg

Эта операция займет некоторое время, так что можно даже успеть выпить чашку чая. Этот список включает в себя различные утилиты и библиотеки, например, веб-сервер Apache и “carto“, который используется для преобразования таблиц стилей Carto-CSS в то, что ”mapnik” уже может потом использовать при генерации (рендеринге) тайлов. Когда установка завершится, установите второй набор необходимых компонентов:

Установка postgresql / postgis

В Ubuntu есть готовые версии как postgis, так и postgresql, поэтому их можно просто установить с помощью менеджера пакетов Ubuntu.

sudo apt-get install postgresql postgresql-contrib postgis postgresql-10-postgis-2.4 postgresql-10-postgis-scripts

“postgresql“ - это база данных, в которой мы будем хранить данные карты, а ”postgis” добавляет к ней дополнительную географическую поддержку.

Теперь вам нужно создать базу данных Postgis. По умолчанию различные программы предполагают, что база данных называется gis. Мы тоже будем использовать в своей инструкции такое же название, хотя в этом нет никакой необходимости. Вы должны указать свое имя пользователя вместо “renderaccount”, где оно используется ниже. Это должно быть имя пользователя, который будет генерировать тайлы с помощью Mapnik.

sudo -u postgres -i
createuser renderaccount # answer yes for superuser (although this isn't strictly necessary)
createdb -E UTF8 -O renderaccount gis

Пока вы всё ещё работаете от имени пользователя “postgres”, установите PostGIS на базу PostgreSQL (опять же, заменив renderaccount на своё имя пользователя):

psql

(вы увидите приглашение “postgres=#”)

\c gis

(в ответ вы получите “You are now connected to database ‘gis’ as user ‘postgres’”)

CREATE EXTENSION postgis;

(в ответ вы получите “CREATE EXTENSION”)

CREATE EXTENSION hstore;

(в ответ вы получите “CREATE EXTENSION”)

ALTER TABLE geometry_columns OWNER TO renderaccount;

(в ответ вы получите “ALTER TABLE”)

ALTER TABLE spatial_ref_sys OWNER TO renderaccount;

(в ответ вы получите “ALTER TABLE”)

\q

(при этом вы выйдите из psql и вернётесь к обычной командной строке Linux)

exit

(чтобы вернуться к пользователю, под которым вы работали до команды “sudo -u postgres -i”)

Если вы ещё не создали, то также создайте Unix-пользователя с соответствующим именем, введя пароль по запросу:

sudo useradd -m renderaccount
sudo passwd renderaccount

Опять же, замените “renderaccount” на то имя пользователя (не root), которое вы ранее выбрали.

Установка osm2pgsql

Часть программного обеспечения необходимо собрать из исходников. Первое из них - это “osm2pgsql”. Есть разные инструменты для импорта и управления данными OpenStreetMap в базах данных, но мы будем использовать именно этот, так как он наиболее популярный.

mkdir ~/src
cd ~/src
git clone git://github.com/openstreetmap/osm2pgsql.git
cd osm2pgsql

Механизм сборки osm2pgsql изменился по сравнению со старыми версиями, так что вам потребуется установить ещё немного зависимостей:

sudo apt install make cmake g++ libboost-dev libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libgeos-dev libgeos++-dev libproj-dev lua5.2 liblua5.2-dev

Опять же, ответьте yes для установки.

mkdir build && cd build
cmake ..

(Вывод этих команд должен закончится сообщениями “build files have been written to”)

make

(Эта команда должна завершиться сообщением “[100%] Built target osm2pgsql”)

sudo make install

Mapnik

Далее устанавливаем Mapnik. Мы будем использовать ту версию, которая идет по умолчанию в Ubuntu 18.04:

sudo apt-get install autoconf apache2-dev libtool libxml2-dev libbz2-dev libgeos-dev libgeos++-dev libproj-dev gdal-bin libmapnik-dev mapnik-utils python-mapnik

Проверим, правильно ли установился Mapnik:

python
>>> import mapnik
>>>

Если python в ответ снова выводит приглашение »> без ошибок, значит, библиотека Mapnik найдена Python. Поздравляем! Вы можете выйти из Python с помощью команды:

>>> quit()

Установка mod_tile и renderd

Далее мы установим mod_tile и renderd. “mod_tile” - это модуль Apache, который обрабатывает запросы на тайлы. “renderd” - это фоновая программа, которая фактически генерирует (рендерит) тайлы, когда “mod_tile” запрашивает их. Мы будем использовать форк “mod_tile” - “switch2osm”, который модифицирован для Ubuntu 18.04 и использованию на стандартном сервере Ubuntu, а не на одном из серверов генерации (рендеринга) OSM.

Компиляция mod_tile из исходников:

cd ~/src
git clone -b switch2osm git://github.com/SomeoneElseOSM/mod_tile.git
cd mod_tile
./autogen.sh

(в конце вы должны получить “autoreconf: Leaving directory ‘.’”)

./configure

(в конце вы должны получить “config.status: executing libtool commands”)

make

Обратите внимание, что на этом этапе будут выскакивать некоторые “предупреждающие” сообщения. Тем не менее, всё должно закончиться сообщением “make[1]: Leaving directory ‘/home/renderaccount/src/mod_tile’”.

sudo make install

(Это должно закончиться сообщением “make[1]: Leaving directory ‘/home/renderaccount/src/mod_tile’”)

sudo make install-mod_tile

(Это должно закончиться сообщением “chmod 644 /usr/lib/apache2/modules/mod_tile.so”)

sudo ldconfig

(Тут не должно быть никаких сообщений)

Настройка таблицы стилей

Теперь, когда все необходимое программное обеспечение установлено, вам нужно будет скачать и настроить таблицу стилей.

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

Несмотря на то, что у “OpenStreetMap Carto” есть свой домашний сайт и собственные инструкции по установке, все же мы расскажем, что необходимо сделать для его настройки.

Предполагается, что мы разместим файлы стиля в подкаталоге src домашней директории пользователя “renderaccount” (или какое там вы использовали).

cd ~/src
git clone git://github.com/gravitystorm/openstreetmap-carto.git
cd openstreetmap-carto

Далее установим подходящую версию компилятора carto. Она новее, чем версия, идущая вместе с Ubuntu, так что нам необходимо сделать следующее:

sudo apt install npm nodejs
sudo npm install -g carto
carto -v

В ответ мы получем значение, которое должно быть не меньше, чем:

carto 1.1.0 (Carto map stylesheet compiler)

Затем преобразуем проект carto в то, что понимает Mapnik:

carto project.mml > mapnik.xml

Теперь у вас есть XML-стиль Mapnik в файле /home/renderaccount/src/openstreetmap-carto/mapnik.xml.

Загрузка данных

В качестве примера мы загрузим небольшой объем тестовых данных. Их можно скачать в разных местах, но “download.geofabrik.de” предлагает весьма широкий выбор. Попробуем, например, скачать Азербайджан (~19 Мб).

Зайдите на страничку “Azerbaijan” на сайте Geofabrik и обратите внимание на дату “This file was modified” (что-то вида “2019-12-22T21:59:02Z”). Нам она потребуется, если мы захотим после обновлять свою базу данных. Скачайте данные по Азербайджану следующим образом:

mkdir ~/data
cd ~/data
wget http://download.geofabrik.de/asia/azerbaijan-latest.osm.pbf

Следующая команда вставит в базу данных скачанные данные из OpenStreetMap. Во время этой операции значительно увеличится нагрузка на жесткий диск. Импорт всей планеты может занять несколько часов, дней или даже недель в зависимости от мощности вашего оборудования. Небольшие выгрузки, конечно, импортируются значительно быстрее, но в любом случае вам может потребоваться поэкспериментировать с различными значениями -C, чтобы уместиться в доступную оперативную память вашего сервера.

osm2pgsql -d gis --create --slim  -G --hstore --tag-transform-script ~/src/openstreetmap-carto/openstreetmap-carto.lua -C 2500 --number-processes 1 -S ~/src/openstreetmap-carto/openstreetmap-carto.style ~/data/azerbaijan-latest.osm.pbf

Полезно пояснить, что означают эти опции:

-d gis

База данных, с которой мы работаем (“gis” использовалась по умолчанию, но теперь это надо указывать)

--create

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

--slim

osm2pgsql может использовать различные схемы таблиц, “slim” подходит для рендеринга.

-G

Указывает, как обрабатывать мультиполигоны.

--hstore

Позволяет использовать для рендеринга тэги, для которых нет отдельных колонок в базе данных.

--tag-transform-script

Указывает на lua-скрипт, используемый при обработке тэгов. Это простейший способ обрабатывать тэги OSM до того, как они будут обработаны с помощью style-файла, чтобы сделать логику стиля потенциально проще.

-C 2500

Выделяет 2,5 Гб оперативной памяти для osm2pgsql на процесс импорта. Если у вас недостаточно памяти, вы можете попробовать уменьшить это значение, а если процесс импорта будет убит из-за нехватки памяти, вам потребуется уменьшить это число или попробовать выгрузку OSM меньшего объёма.

--number-processes 1

Использует один процесс. Если у вас есть больше процессорных ядер, вы можете указать больше.

-S

Создаёт колонки в базе данных, как указано в этом файле (в данном случае они не будут отличаться от “openstreetmap-carto”)

Последним параметром указан файл для загрузки.

Команда завершится сообщением навроде “Osm2pgsql took 238s overall”.

Загрузка shape-файла

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

cd ~/src/openstreetmap-carto/
scripts/get-shapefiles.py

Этот процесс предполагает скачивание значительного объема информации с интернета и может занять какое-то время. По завершении он должен сообщить “…script completed.”

Шрифты

Названия, используемые для обозначения мест по всему миру, не всегда пишутся латинскими буквами (обычный алфавит “a”-“z”). Для установки необходимых шрифтов сделайте следующее:

sudo apt-get install fonts-noto-cjk fonts-noto-hinted fonts-noto-unhinted ttf-unifont

В инструкции, написанной разработчиками OpenSteetMap Carto, также предлагается установить из исходного кода “Noto Emoji Regular”. Но он может пригодиться только для отображения эмодзи в названиях американских магазинов. Все другие международные шрифты, которые могут понадобиться в работе (в том числе те, которые часто не поддерживаются), включены в список только что установленных.

Настройка вашего веб-сервера

Настраиваем renderd

Конфиг для “renderd” находится в файле “/usr/local/etc/renderd.conf”. Отредактируйте его с помощью текстового редактора, например, nano:

sudo nano /usr/local/etc/renderd.conf

Потребуется изменить несколько строк. В секции “renderd”:

num_threads=4

Если у вас только 2 Гб памяти или около того, вы можете захотеть уменьшить это значение до 2.

Секция “ajt” соответствует картостилю с именем “ajt”. У вас может быть более одной такой секции, использующей разные URI для каждой. Строку “XML” следует изменить на что-то вроде:

XML=/home/renderaccount/src/openstreetmap-carto/mapnik.xml

Вы можете изменить “renderaccount” на имя того не-root-пользователя, что использовали выше.

URI=/hot/

Это выбрано для того, чтобы сгенерированные тайлы, можно было проще использовать заместо слоя HOT на сайте OpenStreetMap.org. Вы можете написать тут что-то ещё, но /hot тоже неплохо.

Настраиваем Apache

sudo mkdir /var/lib/mod_tile
sudo chown renderaccount /var/lib/mod_tile

sudo mkdir /var/run/renderd
sudo chown renderaccount /var/run/renderd

Вы теперь должны сказать Apache о модуле mod_tile, для чего с помощью nano (или другого редактора)

sudo nano /etc/apache2/conf-available/mod_tile.conf

добавьте в файл следующую строку:

LoadModule tile_module /usr/lib/apache2/modules/mod_tile.so

затем сохраните его и выполните::

sudo a2enconf mod_tile

Вы получите сообщение, что необходимо выполнить “service apache2 reload” для активации новой конфигурации, но пока этого делать не нужно.

Теперь надо рассказать Apache про “renderd”. С помощью nano (или иного редактора)

sudo nano /etc/apache2/sites-available/000-default.conf

добавьте следующий код между строками “ServerAdmin” и “DocumentRoot”:

LoadTileConfigFile /usr/local/etc/renderd.conf
ModTileRenderdSocketName /var/run/renderd/renderd.sock
# Timeout before giving up for a tile to be rendered
ModTileRequestTimeout 0
# Timeout before giving up for a tile to be rendered that is otherwise missing
ModTileMissingRequestTimeout 30

И дважды перезапустите Apache:

sudo service apache2 reload
sudo service apache2 reload

(Почему это нужно сделать два раза? Подозреваю, что Apache слегка “тупит”, когда перенастраивается, будучи запущенным).

Если вы откроете в web-браузере адрес http://адрес-вашего-сервера/index.html, то должны увидеть страницу Ubuntu/Apache “It work!”

(Если вы не знаете выданный серверу IP-адрес, то вы можете, скорее всего, можете использовать ifconfig чтобы узнать - если только конфигурации сети не является чересчур сложной - адрес должен быть в строке “inet addr”, но не “127.0.0.1”). Если вы используете сервер у хостинг-провайдера, то, возможно, что внутренний адрес сервера будет отличаться от внешнего, выданного вам, но внешний IP уже должен быть у вас и, вероятно, вы уже работаете с сервером именно по этому адресу.

Обратите внимание, что этот сайт работает только по http (порт 80), вам потребуется сделать больше, чтобы включить в Apache https, но это выходит за рамки нашей инструкции. Тем не менее, если вы используете “Let’s Encrypt” для выпуска сертификатов, то процесс настройки его может также настраивать использование https в Apache.

Запускаем renderd первый раз

Теперь мы запустим renderd, чтобы сгенерировать несколько тайлов. Изначально мы запустим его так, чтобы можно было видеть ошибки по мере их появления:

renderd -f -c /usr/local/etc/renderd.conf

Вы можете увидеть несколько предупреждений, пока не обращайте на них внимания. Вам надо не получить ошибок. Если они будут, сохраните полный вывод и через сайт типа pastebin.com сообщите о проблеме где-нибудь, например, на help.openstreetmap.org (дайте ссылку на pastebin.com - не включайте весь текст в вопрос).

Введите в своем браузере следующий адрес: http://адрес-вашего-сервера/hot/0/0/0.png

Вы должны увидеть карту всего мира в браузере и отладочную информацию в консоли, в том числе сообщения “DEBUG: START TILE” и “DEBUG: DONE TILE”. Игнорируйте “DEBUG: Failed to read cmd on fd” - это не ошибки. Если вы не получили изображение тайла или получили какие-либо ошибки - снова сохраните их в pastebin и задайте вопрос где-нибудь на help.openstreetmap.org.

Если все работает, нажмите CTRL-C, чтобы завершить приложение рендеринга.

Запуск renderd в фоновом режиме

Далее мы настроим “renderd” для запуска в фоновом режиме. Для начала, отредактируйте файл “~/src/mod_tile/debian/renderd.init” и укажите в качестве RUNASUSER того не-root-пользователя типа “renderaccount”, которым вы использовали ранее, далее скопируйте файл в системную директорию:

nano ~/src/mod_tile/debian/renderd.init
sudo cp ~/src/mod_tile/debian/renderd.init /etc/init.d/renderd
sudo chmod u+x /etc/init.d/renderd
sudo cp ~/src/mod_tile/debian/renderd.service /lib/systemd/system/

Файл “renderd.service” - это файл сервиса “systemd”. Используемая тут версия просто вызывает старые init-команды. Чтобы убедиться, что команда start работает, выполните:

sudo /etc/init.d/renderd start

(должно вывести “[ ok ] Starting renderd (via systemctl): renderd.service”.)

Чтобы он всегда запускался автоматически:

sudo systemctl enable renderd

Просмотр тайлов

Чтобы увидеть тайлы, для простоты (???cheat слегка вольно перевёл???) воспользуемся файлом “sample_leaflet.html” в каталлоге “extras” mod_tile. Просто откройте этот файл в браузере на машине, где вы установили тайловый сервер. Если это невозможно и вы установили его на сервер без локального веб-браузера,вы можете отредактировать файл и заменить 127.0.0.1 IP-адресом сервера, затем скопировать его в /var/www/html.

Из ssh-сессии запустите:

tail -f /var/log/syslog | grep " TILE "

(обратите внимание, что тут есть пробелы вокруг “TILE”)

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

Когда вы будете загружать страницу, то должны будете увидеть, как поступают запросы на тайлы. Постепенно уменьшайте масштаб и вы увидите, что запросы на новые тайлы появляются в ssh-соединении. Генерация некоторых тайлов с нуля с низким масштабированием может занять достаточно времени (несколько минут), но зато они быстро загрузятся в следующий раз.

Поздравляем! Теперь вам нужно ознакомиться с разделом “Тайлы”, чтобы сделать карту, которая бы использовала ваш новый тайл-сервер.