Создание тайлового сервера на основе данных OpenStreetMap и mod tile: различия между версиями

Материал из GIS-Lab
Перейти к навигации Перейти к поиску
мНет описания правки
 
(не показана 41 промежуточная версия 4 участников)
Строка 1: Строка 1:
{{Статья|Черновик}}
{{Статья|Опубликована|mod_tile}}
{{Аннотация|Рассматривается процесс создания собственного тайлового сервера на основе данных OpenStreetMap в операционной системе CentOS 6.}}
{{Аннотация|Рассматривается процесс создания собственного тайлового сервера на основе данных OpenStreetMap на примере операционной системы CentOS 6.}}


== Введение ==
== Введение ==


На сегодняшний день в подавляющем большинство картографических веб-приложений в качестве одной из подложек используется слой на базе тайлов [http://www.openstreetmap.org/ OpenStreetMap]. Такая популярность данной подложки обусловлена во-первых [http://wiki.openstreetmap.org/wiki/Tile_usage_policy политикой] предоставления тайлов, позволяющей свободно использовать тайлы OpenStreetMap в своих приложениях, а во-вторых - простотой их подключения в современных веб-клиентах, таких как Leaflet и OpenLayers.
Сегодня во многих картографических веб-приложениях в качестве одной из подложек используется слой на базе тайлов [http://www.openstreetmap.org/ OpenStreetMap]. Популярность данной подложки обусловлена во-первых [http://wiki.openstreetmap.org/wiki/Tile_usage_policy политикой] предоставления тайлов, позволяющей свободно использовать тайлы OpenStreetMap в своих приложениях, а во-вторых - простотой их подключения в современных веб-клиентах, таких как Leaflet и OpenLayers.


Однако иногда возникает необходимость, чтобы данная подложка функционировала в том числе и при отсутствии Интернета (Интранет-приложения). Первым решением данной задачи, которое приходит в голову - это скачать необходимые тайлы с сайта OpenStreetMap. Однако это не очень удачное решение, так как политика использования тайлов запрещает их массовое скачивание и, кроме того, это не гибкий вариант, например, если вы вдруг решите использовать какой-то стиль, отличный от стандартного. Правильным решением данной задачи является получение исходных данных OpenStreetMap и построение на их основе собственного тайлового сервера. Решению данной задачи и посвящена данная статья.
Однако иногда возникает необходимость, чтобы данная подложка функционировала в том числе и при отсутствии Интернета (Интранет-приложения) или, будучи основанной на тех же исходных данных, имела совсем другое представление. Первым решением данной задачи, которое приходит в голову - это скачать необходимые тайлы с сайта OpenStreetMap. Однако это не очень удачное решение, так как политика использования тайлов запрещает их массовое скачивание и, кроме того, данный вариант не позволит настроить собственную символику подложки, отличную от стандартной. Правильным решением данной задачи является получение исходных данных OpenStreetMap и построение на их основе собственного набора тайлов. Решению данной задачи и посвящена данная статья.
 
Набор тайлов может быть подготовлен различными способами, но наиболее универсальный вариант предоставления доступа к тайлам - это использование тайлового сервера - программного обеспечения, работающего по следующим принципами:
* при запросе тайла - сервер проверяет его наличие в своём кэше, если тайл найден - он возвращается клиенту;
* если тайл не найден, то осуществляется его рендеринг, после чего он сохраняется в кэше и только после этого возвращается клиенту.


== Стек программных продуктов тайлового сервера openstreetmap.org ==
== Стек программных продуктов тайлового сервера openstreetmap.org ==


Существуют различные инструменты создания тайловых серверов со своими плюсами и минусами, мы же рассмотрим данный процесс в разрезе стека технологий, применяемых для создания тайлов на сервере openstreetmap.org. Данный стек состоит из 5 компонентов: mod_tile, renderd, Mapnik, osm2pgsql и PostgreSQL/PostGIS. '''mod_tile''' - это модуль веб-сервера Apache, который отдаёт кэшированные тайлы и определяет нуждаются ли те или иные тайлы в отрисовке (в зависимости от того есть ли они в кэше и не истек ли срок их актуальности). '''renderd''' представляет собой систему управления очередью запросов на рендеринг, предназначенную для оптимизации нагрузки такими запросами. '''Mapnik''' - рендерер, используемый renderd. '''osm2pgsql''' - инструмент загрузки исходных данных OpenStreetMap в базу данных '''PostgreSQL/PostGIS'''.
Существуют различные инструменты создания тайловых серверов со своими плюсами и минусами, мы же рассмотрим данный процесс в разрезе стека технологий, применяемых для создания тайлов на сервере openstreetmap.org. Данный стек состоит из 5 компонентов: mod_tile, renderd, Mapnik, osm2pgsql и PostgreSQL/PostGIS.  
 
*'''mod_tile''' - это модуль веб-сервера Apache, который отдаёт кэшированные тайлы и определяет нуждаются ли те или иные тайлы в отрисовке (в зависимости от того есть ли они в кэше и не истек ли срок их актуальности).
*'''renderd''' представляет собой систему управления очередью запросов на рендеринг, предназначенную для оптимизации нагрузки такими запросами.
*'''Mapnik''' - рендерер, превращающий векторные данные в растровые тайлы и используемый renderd.
*'''osm2pgsql''' - инструмент загрузки исходных данных OpenStreetMap в базу данных.
*'''PostgreSQL/PostGIS''' - собственно СУБД.


Данный стек технологий работает только в UNIX-подобных операционных системах и не работает в Windows, так как использует для связи mod_tile и renderd доменные сокеты Unix.
Данный стек технологий работает только в UNIX-подобных операционных системах и не работает в Windows, так как использует для связи mod_tile и renderd доменные сокеты Unix.


Если в качестве операционной системы вы планируете использовать Debian или Ubuntu, то вам лучше обратиться к [http://switch2osm.org/serving-tiles/building-a-tile-server-from-packages/ инструкции] по развертыванию тайлового сервера для данных операционных систем из пакетов. На том же ресурсе имеется [http://switch2osm.org/serving-tiles/manually-building-a-tile-server-12-04/ инструкция] как развернуть тайловый сервер на Ubuntu (Debian) из исходных кодов. В случае же если ваша операционная система отличается от вышеназванных, то полностью следовать описанным в них шагам не получится, так как некоторые из них довольно Debian-специфичны. Вот тут, возможно, и пригодится вам данная статья.
Если в качестве операционной системы вы планируете использовать Debian или Ubuntu, то вам лучше обратиться к [http://switch2osm.org/serving-tiles/building-a-tile-server-from-packages/ инструкции] по развертыванию тайлового сервера для данных операционных систем из пакетов. На том же ресурсе имеется [http://switch2osm.org/serving-tiles/manually-building-a-tile-server-12-04/ инструкция] как развернуть тайловый сервер на Ubuntu (Debian) из исходных кодов. В случае же если ваша операционная система отличается от вышеназванных, то полностью следовать описанным в них шагам не получится, так как некоторые из них довольно Debian-специфичны. Вот тут, возможно, и пригодится данная статья.


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


В качестве базового дистрибутива мы будем рассматривать операционную систему CentOS 6 x86_64. Так как большинство из необходимого ПО (mod_tile, renderd, Mapnik, osm2pgsql) для данной операционной системы отсутствуют (либо устарели), а ставить из исходных кодов не очень хорошо, то предварительно соберем их в [https://github.com/nextgis/gis_packages_centos RPM-пакеты]. Для их удобной установки нами был организован тестовый [http://nextgis.ru/programs/centos/ репозиторий]. Как его подключить и работать с ним будет рассмотрено далее.
В качестве базового дистрибутива мы будем рассматривать операционную систему CentOS 6 x86_64, но вся последовательность шагов может быть легко адаптирована и под любой другой Linux-дистрибутив. Большинство из необходимого ПО (mod_tile, renderd, Mapnik, osm2pgsql) для данной операционной системы в репозиториях по-умолчанию отсутствуют (либо устарели), а ставить из исходных кодов не очень удобно.
 
Поэтому для удобной установки необходимых пакетов лучше использовать [http://nextgis.ru/programs/centos/ специальный репозиторий]. Как его подключить и работать с ним будет рассмотрено далее. Руководство по самостоятельной сборке RPM-пакетов можно почитать [https://github.com/nextgis/gis_packages_centos здесь].  


=== Подключение необходимых репозиториев ===
=== Подключение необходимых репозиториев ===
Строка 30: Строка 42:
<pre>yum localinstall http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm</pre>
<pre>yum localinstall http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm</pre>


В файле конфигурации стандартного репозитория, раположенного по адресу ''/etc/yum.repos.d/CentOS-Base.repo'' в секции ''[base]'' и ''[updates]'' добавьте строку:
В файле конфигурации стандартного репозитория, расположенного по адресу ''/etc/yum.repos.d/CentOS-Base.repo'' в секции ''[base]'' и ''[updates]'' добавьте строку:


<pre>exclude=postgresql*</pre>
<pre>exclude=postgresql*</pre>
Строка 36: Строка 48:
Подключаем репозиторий enetres, содержащий свежую версию библиотеку Boost C++ 1.55, используемую при сборке Mapnik. Для подключения данного репозитория скопируйте [http://repo.enetres.net/enetres.repo файл] в директорию ''/etc/yum.repos.d/''.
Подключаем репозиторий enetres, содержащий свежую версию библиотеку Boost C++ 1.55, используемую при сборке Mapnik. Для подключения данного репозитория скопируйте [http://repo.enetres.net/enetres.repo файл] в директорию ''/etc/yum.repos.d/''.


Подключаем репозиторий nextgis: скопируйте [http://nextgis.ru/programs/centos/nextgis.repo файл] в директорию ''/etc/yum.repos.d/''.
Подключаем репозиторий nextgis, содержащий все остальные необходимые компоненты: скопируйте [http://nextgis.ru/programs/centos/nextgis.repo файл] в директорию ''/etc/yum.repos.d/''.


=== Установка PostgreSQL/PostGIS ===
=== Установка PostgreSQL/PostGIS ===
Строка 70: Строка 82:
su - postgres -c "psql -d gis -c 'ALTER TABLE spatial_ref_sys OWNER TO dr;'"</pre>
su - postgres -c "psql -d gis -c 'ALTER TABLE spatial_ref_sys OWNER TO dr;'"</pre>


Загружаем данные в базу. Будем загружать данные на территорию СНГ:
Загружаем данные в базу. Будем загружать данные на территорию СНГ. Существует несколько способов получения исходных данных OpenStreetMap, один из них - ежедневные выгрузки данных на территорию бывшего СССР в форматах XML и PBF, расположенные [http://gis-lab.info/projects/osm_dump/ здесь].


<pre>
<pre>
Строка 80: Строка 92:


При использовании osm2pgsql мы указали объём выделяемой оперативной памяти 1.5 Гб (''-C'' 1500), включили slim-режим (''--slim'', подробности о режимах загрузки данных можно найти в документации) и активировали загрузку в 4 процесса (''--number-processes'' 4). Кроме того, так как мы не планируем diff-обновления наших данных, то используя ключ ''--drop'', мы автоматически удаляем создаваемые при загрузке данных slim-таблицы, что значительно уменьшает размер нашей базы данных. Загрузка данных будет продолжаться несколько часов, сколько конкретно - зависит от аппаратной част и настроек программного обеспечения, более подробную информацию можно получить в данной [http://www.geofabrik.de/media/2012-09-08-osm2pgsql-performance.pdf презентации].
При использовании osm2pgsql мы указали объём выделяемой оперативной памяти 1.5 Гб (''-C'' 1500), включили slim-режим (''--slim'', подробности о режимах загрузки данных можно найти в документации) и активировали загрузку в 4 процесса (''--number-processes'' 4). Кроме того, так как мы не планируем diff-обновления наших данных, то используя ключ ''--drop'', мы автоматически удаляем создаваемые при загрузке данных slim-таблицы, что значительно уменьшает размер нашей базы данных. Загрузка данных будет продолжаться несколько часов, сколько конкретно - зависит от аппаратной част и настроек программного обеспечения, более подробную информацию можно получить в данной [http://www.geofabrik.de/media/2012-09-08-osm2pgsql-performance.pdf презентации].
== Настройка стилей Mapnik ==
В качестве стилей тайлов будем использовать стандартный стиль OpenStreetMap. Скачиваем файлы с описанием стиля:
<pre>
cd ~/src
svn co http://svn.openstreetmap.org/applications/rendering/mapnik mapnik-style
</pre>
Стандартный файл стилей Mapnik подразумевает, что для создания тайлов, содержащих береговые линии и территории, занимаемые океанами, на мелких масштабах используются отдельные файлы, а не данные из базы, поскольку так гораздо быстрее. Загружаем эти файлы (порядка 400 Мб):
<pre>
cd ~/src/mapnik-style
./get-coastlines.sh /usr/local/share
</pre>
При выполнении данной команды вы получите сообщение об ошибке следующего вида:
<pre>bunzip2 is not installed in /bin/bunzip2, it is needed by this script</pre>
Чтобы узнать, куда у вас в системе установлен ''bunzip2'', выполните команду:
<pre>which bunzip2</pre>
После чего откройте файл ''get-coastlines.sh'' и отредактируйте следующую строку:
<pre>BUNZIP2=/bin/bunzip2</pre>
В нашем случае она выглядит так:
<pre>BUNZIP2=/usr/bin/bunzip2</pre>
После этого снова запускайте этот файл. Должен начаться процесс загрузки данных:
<pre>./get-coastlines.sh /usr/local/share</pre>
После того как все необходимые файлы были получены, необходимо осуществить небольшую правку конфигурационных файлов для адаптации их под свою систему:
<pre>
cd ~/src/mapnik-style/inc
cp fontset-settings.xml.inc.template fontset-settings.xml.inc
cp datasource-settings.xml.inc.template datasource-settings.xml.inc
cp settings.xml.inc.template settings.xml.inc
</pre>
Открываем файл ''settings.xml.inc'' и приводим его к следующему виду:
<syntaxhighlight lang="xml">
<!--
Settings for symbols, the spatial reference of your postgis tables, coastline shapefiles directory, and their prefix names.
-->
<!-- use 'symbols' unless you have moved the symbols directory -->
<!ENTITY symbols "symbols">
<!-- use the '&srs900913;' entity if you have called osm2pgsql without special flags (or with -m); use '&srs4326;' if you have used -l -->
<!ENTITY osm2pgsql_projection "&srs900913;">
<!-- used for 'node in way' ST_DWithin spatial operations -->
<!-- Use 0.1 (meters) when your database is in 900913    -->
<!-- Use 0.000001 (degrees) when your database is in 4326 -->
<!ENTITY dwithin_900913 "0.1">
<!ENTITY dwithin_4326 "0.00001">
<!ENTITY dwithin_node_way "&dwithin_900913;">
<!-- use 'world_boundaries', which is the usual naming for the local folder the coastline shapefiles are unzipped into -->
<!ENTITY world_boundaries "/usr/local/share/world_boundaries">
<!-- use 'planet_osm' unless you have customized your database table prefix using the osm2pgsql 'prefix' flag -->
<!ENTITY prefix "planet_osm">
</syntaxhighlight>
Открываем файл ''datasource-settings.xml.inc'' и приводим его к следующему виду (указав собственный пароль и охват, соответствующий загруженным в базу данным):
<syntaxhighlight lang="xml">
<!--
Settings for your postgres setup.
Note: feel free to leave password, host, port, or use blank
-->
<Parameter name="type">postgis</Parameter>
<Parameter name="password">Ijdg83wk</Parameter>
<!-- <Parameter name="host">%(host)s</Parameter> -->
<!-- <Parameter name="port">%(port)s</Parameter> -->
<Parameter name="user">dr</Parameter>
<Parameter name="dbname">gis</Parameter>
<!-- this should be 'false' if you are manually providing the 'extent' -->
<Parameter name="estimate_extent">false</Parameter>
<!-- manually provided extent in epsg 900913 for whole globe -->
<!-- providing this speeds up Mapnik database queries -->
<Parameter name="extent">-20037508.33,4183149.83,20037508.34,17014106.6</Parameter>
</syntaxhighlight>
'''Замечание:''' начиная с [https://blog.openstreetmap.org/2013/08/26/%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80-%D1%82%D0%B0%D0%B9%D0%BB%D0%BE%D0%B2-%D0%BD%D0%BE%D0%B2%D1%8B%D0%B9-%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%81%D1%82%D0%B8%D0%BB%D1%8C/?lang=ru августа 2013] года, тайлы на сайте openstreetmap.org отрисовываются не с помощью XML-стиля, а с помощью стиля в формате [https://github.com/gravitystorm/openstreetmap-carto CartoCSS]. Это полностью переписанный на CartoCSS старый XML-стиль, что значительно упрощает его модификацию. Стиль сделан как можно более похожим на старый.
== Настройка renderd ==
Откройте файл, содержащий настройки renderd. Данный файл расположен по адресу ''/etc/renderd.conf''. Приведите его к следующему виду (так как в нашем примере файл стилей Mapnik находится в домашнем каталоге пользователя, то отредактируйте значение параметра ''XML'' в соответствии со своим пользователем (в нашем примере имя пользователя в системе и имя пользователя в базе данных совпадают, у вас это могут быть совершенно разные пользователи)):
<syntaxhighlight lang="ini">
[renderd]
socketname=/var/run/renderd/renderd.sock
num_threads=4
tile_dir=/var/lib/mod_tile
stats_file=/var/run/renderd/renderd.stats
[mapnik]
plugins_dir=/usr/lib64/mapnik/input
font_dir=/usr/share/fonts/dejavu
font_dir_recurse=1
[default]
URI=/osm_tiles/
TILEDIR=/var/lib/mod_tile
XML=/home/dr/src/mapnik-style/osm.xml
HOST=localhost
CORS=*
TILESIZE=256
</syntaxhighlight>
Список всех настроек, которые могут быть добавлены в этот файл можно найти [https://github.com/openstreetmap/mod_tile/blob/master/renderd.conf здесь].
Создадим директорию в которую будет помещён Unix-сокет для взаимодействия mod_tile и renderd и директорию, в которой будут храниться кэшированные тайлы (соответствующие пути мы прописали в файле ''renderd.conf''):
<pre>
mkdir /var/run/renderd
mkdir /var/lib/mod_tile
</pre>
Сделаем владельцами данных каталогов пользователя, от имени которого будет запускаться renderd. Пусть в нашем случае это будет системный пользователь dr:
<pre>
chown dr /var/run/renderd
chown dr /var/lib/mod_tile
</pre>
== Настройка mod_tile ==
Если Apache ещё не установлен, то установите его:
<pre>yum install httpd</pre>
Перейдите в директорию с настройками Apache ''/etc/httpd/conf.d'' и создайте там файл ''mod_tile.conf'' следующего содержания:
<syntaxhighlight lang="xml">
LoadModule tile_module /usr/lib64/httpd/modules/mod_tile.so
<VirtualHost *:80>
    ServerName localhost
    ServerAdmin webmaster@localhost
    LoadTileConfigFile /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
    ErrorLog /var/log/httpd/error_log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog /var/log/httpd/access_log combined
</VirtualHost>
</syntaxhighlight>
Описание всех инструкций, которые могут быть добавлены в этот файл можно найти [https://github.com/openstreetmap/mod_tile/blob/master/mod_tile.conf здесь].
== Проверка корректности произведённых настроек ==
Запускаем renderd вручную:
<pre>renderd -f -c /etc/renderd.conf</pre>
Если при запуске вы столкнётесь с [http://gis.stackexchange.com/q/91759/3420 подобной] проблемой, то поставьте в систему пакет ''proj-epsg'':
<pre>yum install proj-epsg</pre>
Включаем возможность автоматической загрузки Apache после перезагрузки системы:
<pre>chkconfig httpd on</pre>
При запущенном renderd в отдельной консоли перезапускаем Apache:
<pre>service httpd restart</pre>
Должно появиться сообщение следующего содержания:
<pre>Starting httpd: [Wed Jul 09 19:45:29 2014] [notice] Loading tile config default at /osm_tiles/ for zooms 0 - 20 from tile directory /var/lib/mod_tile with extension .png and mime type image/png</pre>
Пробуем открыть какой-нибудь тайл, например:
<pre>http://localhost/osm_tiles/0/0/0.png</pre>
Если вы получили тайл с первого раза - значит вам повезло. Если нет, то смотрите интерактивные логи запущенного renderd и логи Apache:
<pre>tail /var/log/httpd/error_log</pre>
Наиболее распространённая ошибка в логах Apache:
<pre>socket connect failed for: /var/run/renderd/renderd.sock with reason: Permission denied</pre>
Проверьте права доступа к сокету для пользователя, от имени которого запущен Apache:
<pre>sudo -u apache ls -lh /var/run/renderd/renderd.sock</pre>
В документации по mod_tile сказано, что SELinux блокирует соединение mod_tile и renderd, поэтому должен быть отключен (требуется перезагрузка). Также в случае возникновения подобных проблем попробуйте отключить сервис iptables, если он запущен.
Как только вам удастся получить готовый тайл - останавливайте renderd (''Ctrl+C''), запущенный в foreground-режиме.
== Автоматический запуск renderd ==
Очевидно, что каждый раз вручную запускать renderd после перезагрузки сервера - это не дело, поэтому нам необходима возможность автоматического запуска renderd. В репозитории mod_tile (renderd входит в его состав) присутствует [https://github.com/openstreetmap/mod_tile/blob/master/debian/renderd.init init-скрипт], выполняющий эту задачу. Однако он Debian-специфичен и нам не подходит. Напишем свой.
Создаём файл ''/etc/init.d/renderd'' следующего содержания:
<syntaxhighlight lang="bash">
#!/bin/bash
#
# renderd    Mapnik rendering daemon
#
# chkconfig: 345 70 30
# description: Mapnik rendering daemon
# processname: renderd
# Source function library.
. /etc/init.d/functions
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Mapnik rendering daemon"
NAME=renderd
DAEMON=/usr/bin/$NAME
DAEMON_ARGS="-c /etc/renderd.conf"
PIDSOCKDIR=/var/run/$NAME
PIDFILE=$PIDSOCKDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
RUNASUSER=dr
start() {
        if [ -e $PIDFILE ];
        then
            echo -n "$NAME already started"
            RETVAL=1
        else
            echo -n "Starting $NAME: "
            [ -d "$PIDSOCKDIR" ] ||  mkdir -p $PIDSOCKDIR && chown $RUNASUSER $PIDSOCKDIR
            daemon --user $RUNASUSER $DAEMON $DAEMON_ARGS 2> /dev/null
            RETVAL=$?
            [ $RETVAL -eq 0 ] && touch $PIDFILE
        fi
        echo
        return $RETVAL
}
stop() {
        echo -n "Shutting down $NAME: "
        killproc $DAEMON && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $PIDFILE
        echo
        return $RETVAL
}
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|restart}"
        exit 1
        ;;
esac
exit $RETVAL
</syntaxhighlight>
Делаем его исполняемым:
<pre>chmod u+x /etc/init.d/renderd</pre>
Запускаем сервис и добавляем его в автозагрузку:
<pre>
service renderd start
chkconfig renderd on
</pre>
== Предварительный рендеринг тайлов ==
В текущей конфигурации тайлы будут отрисовываться по запросу. То есть если mod_tile не найдёт запрашиваемый тайл в кэше, то он обратится за ним к renderd. Однако процесс отрисовки тайлов требует определенного времени и чтобы не заставлять ждать клиента, запрашивающего тайл, пока этот тайл отрисуется, можно подготовить необходимые тайлы заранее. В состав пакета renderd помимо самого демона входит еще несколько вспомогательных утилит, среди которых ''render_list''. С помощью данной утилиты можно указать масштабный уровень и диапазоны x и y координат тайлов и осуществить предварительный рендеринг. Пример рендеринга тайлов 7 уровня на территорию России:
<pre>render_list --socket=/var/run/renderd/renderd.sock --all --max-zoom=7 --min-zoom=7 --min-x=73 --max-x=127 --min-y=18 --max-y=47 --num-threads=4</pre>
Пример Python-скрипта расчета координат тайлов по охвату интересующей области:
<syntaxhighlight lang="python">
# Russia bbox
XMIN = 2989951.00
XMAX = 20037508.34
YMIN = 5039930.86
YMAX = 14222184.29
# Sphere radius
R = 20037508.342789244
for z in range(19):
  r = 2*R/(256*2**z)
  tile_w = tile_h = 256*r
  x_min = (R+XMIN)/tile_w
  x_max = (R+XMAX)/tile_w
  y_min = (R-YMAX)/tile_h
  y_max = (R-YMIN)/tile_h
  print "render_list --socket=/var/run/renderd/renderd.sock --all --max-zoom=%d --min-zoom=%d --min-x=%d --max-x=%d --min-y=%d --max-y=%d --num-threads=4" % (z, z, int(x_min), int(x_max), int(y_min), int(y_max))
</syntaxhighlight>
Для получения списка тайлов в прямоугольнике с координатами WGS-84, либо по произвольному полигону обрезки, воспользуйтесь [https://github.com/zverik/polytiles polytiles.py]. Пример команды:
./polytiles.py --poly russia.poly --zooms 6 10 --export russia_tiles.lst -q
render_list -s /run/renderd/renderd.sock < russia_tiles.lst
== Актуальность тайлов ==
Чтобы поддерживать тайлы в актуальном состоянии, mod_tile должен знать дату на которую были загружены исходные данные в базу PostGIS. В случае, если дата загрузки данных в базу свежее даты создания тайла, то при следующем обращении к этому тайлу он будет отрисован заново. Дата загрузки данных в базу хранится как timestamp файла ''planet-import-complete'', который должен находиться в директории с тайлами:
<pre>touch /var/lib/mod_tile/planet-import-complete</pre>
== Ежеминутное обновление ==
Чтобы обновлять данные в базе, не обязательно каждый раз обрабатывать всю выгрузку (а то и планету) целиком: достаточно настроить ежеминутное обновление данных базы. На сервер OSM выкладываются [http://planet.osm.org/replication/ файлы изменений] за эти периоды, и с помощью osmosis и osm2pgsql их можно накатить на рабочую базу. Если вы планируете подобного рода обновления, то данные должны быть загружены в базу с помощью osm2pgsql без использования ключа ''--drop''.
Если вы собирали mod_tile из исходников, найдите там файл <tt>openstreetmap-tiles-update-expire</tt>, иначе скачайте его c [https://github.com/openstreetmap/mod_tile/blob/master/openstreetmap-tiles-update-expire github]. Поправьте пути в начале файла. Запускать скрипт нужно от имени пользователя, который запускает renderd и прочее (по инструкции выше — <tt>dr</tt>). Сначала нужно инициализировать рабочие каталоги: запустите
./openstreetmap-tiles-update-expire YYYY-MM-DD
где дата — день, когда был подготовлен загруженный в базу данных дамп. Если будет на день-два раньше — ничего страшного, дублирования не произойдёт. Дальше всё просто: запустите <tt>crontab -e</tt> от пользователя <tt>dr</tt> и добавьте строку:
* * * * * /путь/к/openstreetmap-tiles-update-expire
Проверить, что обновление идёт без ошибок, можно по логу в <tt>/var/log/tiles/run.log</tt>. При полном обновлении базы данных не забывайте отключать вызов скрипта в crontab. Пока он остановлен, можно скачать правильный state.NNN.txt в <tt>/var/lib/mod_tile/.osmosis/state.txt</tt>, чтобы начать обновление с более ранней даты. Максимальный интервал, на который обновляется база за один вызов скрипта, указывается в файле <tt>/var/lib/mod_tile/.osmosis/configuration.txt</tt> в ключе <tt>maxInterval</tt>, по умолчанию — один час.
== Полезные ссылки ==
* [https://github.com/openstreetmap/mod_tile mod_tile]
* [https://github.com/openstreetmap/osm2pgsql osm2pgsql]
* [https://github.com/mapnik/mapnik Mapnik]
* [http://switch2osm.org/ switch2osm]
* [http://vladimir-stupin.blogspot.ru/2012/07/mapnik.html Подготовка карт для генератора тайлов Mapnik]
* [http://vladimir-stupin.blogspot.ru/2012/07/mapnik_29.html Настройка базы данных для генератора тайлов Mapnik]
* [http://vladimir-stupin.blogspot.ru/2012/08/mapnik.html Установка генератора тайлов Mapnik]
* [http://vladimir-stupin.blogspot.ru/2012/08/renderd-modtile.html Установка renderd и mod_tile - системы отрисовки тайлов по запросу]
* [http://vladimir-stupin.blogspot.ru/2012/08/blog-post.html Тайловый сервер - что с ним делать?]

Текущая версия от 16:46, 18 июля 2014

Эта страница опубликована в основном списке статей сайта
по адресу http://gis-lab.info/qa/mod_tile.html


Рассматривается процесс создания собственного тайлового сервера на основе данных OpenStreetMap на примере операционной системы CentOS 6.

Введение

Сегодня во многих картографических веб-приложениях в качестве одной из подложек используется слой на базе тайлов OpenStreetMap. Популярность данной подложки обусловлена во-первых политикой предоставления тайлов, позволяющей свободно использовать тайлы OpenStreetMap в своих приложениях, а во-вторых - простотой их подключения в современных веб-клиентах, таких как Leaflet и OpenLayers.

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

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

  • при запросе тайла - сервер проверяет его наличие в своём кэше, если тайл найден - он возвращается клиенту;
  • если тайл не найден, то осуществляется его рендеринг, после чего он сохраняется в кэше и только после этого возвращается клиенту.

Стек программных продуктов тайлового сервера openstreetmap.org

Существуют различные инструменты создания тайловых серверов со своими плюсами и минусами, мы же рассмотрим данный процесс в разрезе стека технологий, применяемых для создания тайлов на сервере openstreetmap.org. Данный стек состоит из 5 компонентов: mod_tile, renderd, Mapnik, osm2pgsql и PostgreSQL/PostGIS.

  • mod_tile - это модуль веб-сервера Apache, который отдаёт кэшированные тайлы и определяет нуждаются ли те или иные тайлы в отрисовке (в зависимости от того есть ли они в кэше и не истек ли срок их актуальности).
  • renderd представляет собой систему управления очередью запросов на рендеринг, предназначенную для оптимизации нагрузки такими запросами.
  • Mapnik - рендерер, превращающий векторные данные в растровые тайлы и используемый renderd.
  • osm2pgsql - инструмент загрузки исходных данных OpenStreetMap в базу данных.
  • PostgreSQL/PostGIS - собственно СУБД.

Данный стек технологий работает только в UNIX-подобных операционных системах и не работает в Windows, так как использует для связи mod_tile и renderd доменные сокеты Unix.

Если в качестве операционной системы вы планируете использовать Debian или Ubuntu, то вам лучше обратиться к инструкции по развертыванию тайлового сервера для данных операционных систем из пакетов. На том же ресурсе имеется инструкция как развернуть тайловый сервер на Ubuntu (Debian) из исходных кодов. В случае же если ваша операционная система отличается от вышеназванных, то полностью следовать описанным в них шагам не получится, так как некоторые из них довольно Debian-специфичны. Вот тут, возможно, и пригодится данная статья.

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

В качестве базового дистрибутива мы будем рассматривать операционную систему CentOS 6 x86_64, но вся последовательность шагов может быть легко адаптирована и под любой другой Linux-дистрибутив. Большинство из необходимого ПО (mod_tile, renderd, Mapnik, osm2pgsql) для данной операционной системы в репозиториях по-умолчанию отсутствуют (либо устарели), а ставить из исходных кодов не очень удобно.

Поэтому для удобной установки необходимых пакетов лучше использовать специальный репозиторий. Как его подключить и работать с ним будет рассмотрено далее. Руководство по самостоятельной сборке RPM-пакетов можно почитать здесь.

Подключение необходимых репозиториев

Подключаем репозиторий EPEL 6:

yum localinstall http://fedora-mirror01.rbc.ru/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Подключаем репозиторий с PostgreSQL:

yum localinstall http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm

В файле конфигурации стандартного репозитория, расположенного по адресу /etc/yum.repos.d/CentOS-Base.repo в секции [base] и [updates] добавьте строку:

exclude=postgresql*

Подключаем репозиторий enetres, содержащий свежую версию библиотеку Boost C++ 1.55, используемую при сборке Mapnik. Для подключения данного репозитория скопируйте файл в директорию /etc/yum.repos.d/.

Подключаем репозиторий nextgis, содержащий все остальные необходимые компоненты: скопируйте файл в директорию /etc/yum.repos.d/.

Установка PostgreSQL/PostGIS

Устанавливаем PostgreSQL:

yum install postgresql93-server
service postgresql-9.3 initdb
service postgresql-9.3 start
chkconfig postgresql-9.3 on

Устанавливаем PostGIS:

yum install postgis2_93

Установка mod_tile, renderd, Mapnik, osm2pgsql

Устанавливаем основные инструменты:

yum install apache2-mod_tile renderd mapnik mapnik-python osm2pgsql

Создание базы данных и загрузка данных

Создаём суперпользователя от имени которого будет вестись работа с базой данных(назовём его dr, а базу данных gis):

su - postgres -c "createuser dr -s -P -e"
su - postgres -c "createdb -E UTF8 -O dr gis"

Загружаем функции PostGIS:

su - postgres -c "psql -d gis -c 'CREATE EXTENSION postgis;'"
su - postgres -c "psql -d gis -c 'ALTER TABLE geometry_columns OWNER TO dr;'"
su - postgres -c "psql -d gis -c 'ALTER TABLE spatial_ref_sys OWNER TO dr;'"

Загружаем данные в базу. Будем загружать данные на территорию СНГ. Существует несколько способов получения исходных данных OpenStreetMap, один из них - ежедневные выгрузки данных на территорию бывшего СССР в форматах XML и PBF, расположенные здесь.

mkdir ~/src
cd ~/src
wget http://data.gis-lab.info/osm_dump/dump/latest/local.osm.pbf
osm2pgsql -U dr -W --slim -C 1500 --number-processes 4 -d gis --drop local.osm.pbf

При использовании osm2pgsql мы указали объём выделяемой оперативной памяти 1.5 Гб (-C 1500), включили slim-режим (--slim, подробности о режимах загрузки данных можно найти в документации) и активировали загрузку в 4 процесса (--number-processes 4). Кроме того, так как мы не планируем diff-обновления наших данных, то используя ключ --drop, мы автоматически удаляем создаваемые при загрузке данных slim-таблицы, что значительно уменьшает размер нашей базы данных. Загрузка данных будет продолжаться несколько часов, сколько конкретно - зависит от аппаратной част и настроек программного обеспечения, более подробную информацию можно получить в данной презентации.

Настройка стилей Mapnik

В качестве стилей тайлов будем использовать стандартный стиль OpenStreetMap. Скачиваем файлы с описанием стиля:

cd ~/src
svn co http://svn.openstreetmap.org/applications/rendering/mapnik mapnik-style

Стандартный файл стилей Mapnik подразумевает, что для создания тайлов, содержащих береговые линии и территории, занимаемые океанами, на мелких масштабах используются отдельные файлы, а не данные из базы, поскольку так гораздо быстрее. Загружаем эти файлы (порядка 400 Мб):

cd ~/src/mapnik-style
./get-coastlines.sh /usr/local/share

При выполнении данной команды вы получите сообщение об ошибке следующего вида:

bunzip2 is not installed in /bin/bunzip2, it is needed by this script

Чтобы узнать, куда у вас в системе установлен bunzip2, выполните команду:

which bunzip2

После чего откройте файл get-coastlines.sh и отредактируйте следующую строку:

BUNZIP2=/bin/bunzip2

В нашем случае она выглядит так:

BUNZIP2=/usr/bin/bunzip2

После этого снова запускайте этот файл. Должен начаться процесс загрузки данных:

./get-coastlines.sh /usr/local/share

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

cd ~/src/mapnik-style/inc
cp fontset-settings.xml.inc.template fontset-settings.xml.inc
cp datasource-settings.xml.inc.template datasource-settings.xml.inc
cp settings.xml.inc.template settings.xml.inc

Открываем файл settings.xml.inc и приводим его к следующему виду:

<!--
Settings for symbols, the spatial reference of your postgis tables, coastline shapefiles directory, and their prefix names.
-->

<!-- use 'symbols' unless you have moved the symbols directory -->
<!ENTITY symbols "symbols">

<!-- use the '&srs900913;' entity if you have called osm2pgsql without special flags (or with -m); use '&srs4326;' if you have used -l -->
<!ENTITY osm2pgsql_projection "&srs900913;">

<!-- used for 'node in way' ST_DWithin spatial operations -->
<!-- Use 0.1 (meters) when your database is in 900913     -->
<!-- Use 0.000001 (degrees) when your database is in 4326 -->
<!ENTITY dwithin_900913 "0.1">
<!ENTITY dwithin_4326 "0.00001">
<!ENTITY dwithin_node_way "&dwithin_900913;">

<!-- use 'world_boundaries', which is the usual naming for the local folder the coastline shapefiles are unzipped into -->
<!ENTITY world_boundaries "/usr/local/share/world_boundaries">

<!-- use 'planet_osm' unless you have customized your database table prefix using the osm2pgsql 'prefix' flag -->
<!ENTITY prefix "planet_osm">

Открываем файл datasource-settings.xml.inc и приводим его к следующему виду (указав собственный пароль и охват, соответствующий загруженным в базу данным):

<!--
Settings for your postgres setup.

Note: feel free to leave password, host, port, or use blank
-->

<Parameter name="type">postgis</Parameter>
<Parameter name="password">Ijdg83wk</Parameter>
<!-- <Parameter name="host">%(host)s</Parameter> -->
<!-- <Parameter name="port">%(port)s</Parameter> -->
<Parameter name="user">dr</Parameter>
<Parameter name="dbname">gis</Parameter>
<!-- this should be 'false' if you are manually providing the 'extent' -->
<Parameter name="estimate_extent">false</Parameter>
<!-- manually provided extent in epsg 900913 for whole globe -->
<!-- providing this speeds up Mapnik database queries -->
<Parameter name="extent">-20037508.33,4183149.83,20037508.34,17014106.6</Parameter>

Замечание: начиная с августа 2013 года, тайлы на сайте openstreetmap.org отрисовываются не с помощью XML-стиля, а с помощью стиля в формате CartoCSS. Это полностью переписанный на CartoCSS старый XML-стиль, что значительно упрощает его модификацию. Стиль сделан как можно более похожим на старый.

Настройка renderd

Откройте файл, содержащий настройки renderd. Данный файл расположен по адресу /etc/renderd.conf. Приведите его к следующему виду (так как в нашем примере файл стилей Mapnik находится в домашнем каталоге пользователя, то отредактируйте значение параметра XML в соответствии со своим пользователем (в нашем примере имя пользователя в системе и имя пользователя в базе данных совпадают, у вас это могут быть совершенно разные пользователи)):

[renderd]
socketname=/var/run/renderd/renderd.sock
num_threads=4
tile_dir=/var/lib/mod_tile
stats_file=/var/run/renderd/renderd.stats

[mapnik]
plugins_dir=/usr/lib64/mapnik/input
font_dir=/usr/share/fonts/dejavu
font_dir_recurse=1

[default]
URI=/osm_tiles/
TILEDIR=/var/lib/mod_tile
XML=/home/dr/src/mapnik-style/osm.xml
HOST=localhost
CORS=*
TILESIZE=256

Список всех настроек, которые могут быть добавлены в этот файл можно найти здесь.

Создадим директорию в которую будет помещён Unix-сокет для взаимодействия mod_tile и renderd и директорию, в которой будут храниться кэшированные тайлы (соответствующие пути мы прописали в файле renderd.conf):

mkdir /var/run/renderd
mkdir /var/lib/mod_tile

Сделаем владельцами данных каталогов пользователя, от имени которого будет запускаться renderd. Пусть в нашем случае это будет системный пользователь dr:

chown dr /var/run/renderd
chown dr /var/lib/mod_tile

Настройка mod_tile

Если Apache ещё не установлен, то установите его:

yum install httpd

Перейдите в директорию с настройками Apache /etc/httpd/conf.d и создайте там файл mod_tile.conf следующего содержания:

LoadModule tile_module /usr/lib64/httpd/modules/mod_tile.so

<VirtualHost *:80>
    ServerName localhost
    ServerAdmin webmaster@localhost

    LoadTileConfigFile /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

    ErrorLog /var/log/httpd/error_log

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn

    CustomLog /var/log/httpd/access_log combined

</VirtualHost>

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

Проверка корректности произведённых настроек

Запускаем renderd вручную:

renderd -f -c /etc/renderd.conf

Если при запуске вы столкнётесь с подобной проблемой, то поставьте в систему пакет proj-epsg:

yum install proj-epsg

Включаем возможность автоматической загрузки Apache после перезагрузки системы:

chkconfig httpd on

При запущенном renderd в отдельной консоли перезапускаем Apache:

service httpd restart

Должно появиться сообщение следующего содержания:

Starting httpd: [Wed Jul 09 19:45:29 2014] [notice] Loading tile config default at /osm_tiles/ for zooms 0 - 20 from tile directory /var/lib/mod_tile with extension .png and mime type image/png

Пробуем открыть какой-нибудь тайл, например:

http://localhost/osm_tiles/0/0/0.png

Если вы получили тайл с первого раза - значит вам повезло. Если нет, то смотрите интерактивные логи запущенного renderd и логи Apache:

tail /var/log/httpd/error_log

Наиболее распространённая ошибка в логах Apache:

socket connect failed for: /var/run/renderd/renderd.sock with reason: Permission denied

Проверьте права доступа к сокету для пользователя, от имени которого запущен Apache:

sudo -u apache ls -lh /var/run/renderd/renderd.sock

В документации по mod_tile сказано, что SELinux блокирует соединение mod_tile и renderd, поэтому должен быть отключен (требуется перезагрузка). Также в случае возникновения подобных проблем попробуйте отключить сервис iptables, если он запущен.

Как только вам удастся получить готовый тайл - останавливайте renderd (Ctrl+C), запущенный в foreground-режиме.

Автоматический запуск renderd

Очевидно, что каждый раз вручную запускать renderd после перезагрузки сервера - это не дело, поэтому нам необходима возможность автоматического запуска renderd. В репозитории mod_tile (renderd входит в его состав) присутствует init-скрипт, выполняющий эту задачу. Однако он Debian-специфичен и нам не подходит. Напишем свой.

Создаём файл /etc/init.d/renderd следующего содержания:

#!/bin/bash
#
# renderd    Mapnik rendering daemon
#
# chkconfig: 345 70 30
# description: Mapnik rendering daemon
# processname: renderd
 
# Source function library.
. /etc/init.d/functions

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Mapnik rendering daemon"
NAME=renderd
DAEMON=/usr/bin/$NAME
DAEMON_ARGS="-c /etc/renderd.conf"
PIDSOCKDIR=/var/run/$NAME
PIDFILE=$PIDSOCKDIR/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
RUNASUSER=dr

start() {
        if [ -e $PIDFILE ];
        then
            echo -n "$NAME already started"
            RETVAL=1
        else
            echo -n "Starting $NAME: "
            [ -d "$PIDSOCKDIR" ] ||  mkdir -p $PIDSOCKDIR && chown $RUNASUSER $PIDSOCKDIR
            daemon --user $RUNASUSER $DAEMON $DAEMON_ARGS 2> /dev/null
            RETVAL=$?
            [ $RETVAL -eq 0 ] && touch $PIDFILE
        fi
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $NAME: "
        killproc $DAEMON && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $PIDFILE
        echo
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Делаем его исполняемым:

chmod u+x /etc/init.d/renderd

Запускаем сервис и добавляем его в автозагрузку:

service renderd start
chkconfig renderd on

Предварительный рендеринг тайлов

В текущей конфигурации тайлы будут отрисовываться по запросу. То есть если mod_tile не найдёт запрашиваемый тайл в кэше, то он обратится за ним к renderd. Однако процесс отрисовки тайлов требует определенного времени и чтобы не заставлять ждать клиента, запрашивающего тайл, пока этот тайл отрисуется, можно подготовить необходимые тайлы заранее. В состав пакета renderd помимо самого демона входит еще несколько вспомогательных утилит, среди которых render_list. С помощью данной утилиты можно указать масштабный уровень и диапазоны x и y координат тайлов и осуществить предварительный рендеринг. Пример рендеринга тайлов 7 уровня на территорию России:

render_list --socket=/var/run/renderd/renderd.sock --all --max-zoom=7 --min-zoom=7 --min-x=73 --max-x=127 --min-y=18 --max-y=47 --num-threads=4

Пример Python-скрипта расчета координат тайлов по охвату интересующей области:

# Russia bbox
XMIN = 2989951.00
XMAX = 20037508.34
YMIN = 5039930.86
YMAX = 14222184.29

# Sphere radius
R = 20037508.342789244

for z in range(19):
  r = 2*R/(256*2**z)

  tile_w = tile_h = 256*r

  x_min = (R+XMIN)/tile_w
  x_max = (R+XMAX)/tile_w
  y_min = (R-YMAX)/tile_h
  y_max = (R-YMIN)/tile_h

  print "render_list --socket=/var/run/renderd/renderd.sock --all --max-zoom=%d --min-zoom=%d --min-x=%d --max-x=%d --min-y=%d --max-y=%d --num-threads=4" % (z, z, int(x_min), int(x_max), int(y_min), int(y_max))

Для получения списка тайлов в прямоугольнике с координатами WGS-84, либо по произвольному полигону обрезки, воспользуйтесь polytiles.py. Пример команды:

./polytiles.py --poly russia.poly --zooms 6 10 --export russia_tiles.lst -q
render_list -s /run/renderd/renderd.sock < russia_tiles.lst

Актуальность тайлов

Чтобы поддерживать тайлы в актуальном состоянии, mod_tile должен знать дату на которую были загружены исходные данные в базу PostGIS. В случае, если дата загрузки данных в базу свежее даты создания тайла, то при следующем обращении к этому тайлу он будет отрисован заново. Дата загрузки данных в базу хранится как timestamp файла planet-import-complete, который должен находиться в директории с тайлами:

touch /var/lib/mod_tile/planet-import-complete

Ежеминутное обновление

Чтобы обновлять данные в базе, не обязательно каждый раз обрабатывать всю выгрузку (а то и планету) целиком: достаточно настроить ежеминутное обновление данных базы. На сервер OSM выкладываются файлы изменений за эти периоды, и с помощью osmosis и osm2pgsql их можно накатить на рабочую базу. Если вы планируете подобного рода обновления, то данные должны быть загружены в базу с помощью osm2pgsql без использования ключа --drop.

Если вы собирали mod_tile из исходников, найдите там файл openstreetmap-tiles-update-expire, иначе скачайте его c github. Поправьте пути в начале файла. Запускать скрипт нужно от имени пользователя, который запускает renderd и прочее (по инструкции выше — dr). Сначала нужно инициализировать рабочие каталоги: запустите

./openstreetmap-tiles-update-expire YYYY-MM-DD

где дата — день, когда был подготовлен загруженный в базу данных дамп. Если будет на день-два раньше — ничего страшного, дублирования не произойдёт. Дальше всё просто: запустите crontab -e от пользователя dr и добавьте строку:

* * * * * /путь/к/openstreetmap-tiles-update-expire

Проверить, что обновление идёт без ошибок, можно по логу в /var/log/tiles/run.log. При полном обновлении базы данных не забывайте отключать вызов скрипта в crontab. Пока он остановлен, можно скачать правильный state.NNN.txt в /var/lib/mod_tile/.osmosis/state.txt, чтобы начать обновление с более ранней даты. Максимальный интервал, на который обновляется база за один вызов скрипта, указывается в файле /var/lib/mod_tile/.osmosis/configuration.txt в ключе maxInterval, по умолчанию — один час.

Полезные ссылки