Добавил возможность обновления локального файла .osm.pbf
parent
2ecaeee50a
commit
5729dc92eb
18
Dockerfile
18
Dockerfile
|
@ -1,10 +1,14 @@
|
|||
FROM debian:sid AS build
|
||||
MAINTAINER Vitaliy Filippov <vitalif@mail.ru>
|
||||
|
||||
ADD etc /etc
|
||||
# Используем одинаковое начало для ускорения сборки
|
||||
ADD [ "etc/apt/apt.conf", "/etc/apt/" ]
|
||||
ADD etc/locale.gen /etc/locale.gen
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
|
||||
less wget sudo curl unzip git mc ca-certificates gnupg2 && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
|
||||
less wget sudo curl unzip git mc ca-certificates \
|
||||
build-essential golang-go libleveldb-dev libgeos-dev && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
@ -20,13 +24,17 @@ RUN dpkg -l | grep libgeos | awk '{print $2}' >> /root/pkg.lst
|
|||
FROM debian:sid AS run
|
||||
MAINTAINER Vitaliy Filippov <vitalif@mail.ru>
|
||||
|
||||
ADD etc /etc
|
||||
# Используем одинаковое начало для ускорения сборки
|
||||
ADD [ "etc/apt/apt.conf", "/etc/apt/" ]
|
||||
ADD etc/locale.gen /etc/locale.gen
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
|
||||
less wget sudo curl unzip git mc ca-certificates gnupg2 && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=build /root/pkg.lst /root/
|
||||
|
||||
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y -q \
|
||||
less wget sudo curl unzip git mc \
|
||||
`cat /root/pkg.lst` libleveldb1v5 libdbd-pg-perl && \
|
||||
osmctools `cat /root/pkg.lst` libleveldb1v5 libdbd-pg-perl && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=build /root/go/src/github.com/omniscale/imposm3/imposm /usr/bin/imposm3
|
||||
|
|
|
@ -7,7 +7,8 @@ docker build -t imposm3 .
|
|||
## Running
|
||||
|
||||
```
|
||||
docker run -it -d --restart always \
|
||||
-v /home/test/russia-latest.osm.pbf:/home/valhalla/data.osm.pbf \
|
||||
--name valhalla -p 8002:8002 valhalla
|
||||
docker run -t --rm=true \
|
||||
-e OSM_CACHE_DIR=/home/data \
|
||||
-v /home/data/osm:/home/data \
|
||||
--name imposm3 imposm3
|
||||
```
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
en_US.UTF-8 UTF-8
|
||||
ru_RU.UTF-8 UTF-8
|
|
@ -1,6 +1,19 @@
|
|||
#!/usr/bin/perl
|
||||
# Configuration in env: OSM_CACHE_DIR, OSM_CARTO_VERSION, URL_LATEST, URL_UPDATES,
|
||||
# plus PG_ENV_OSM_{DB,HOST,PORT,USER,PASSWORD} like in README for the render server itself
|
||||
# Конфигурация в переменных окружения:
|
||||
#
|
||||
# OSM_CACHE_DIR - путь к директории с временными и загружаемыми файлами
|
||||
# OSM_INIT - если 1, то при пустой базе инициализировать базу
|
||||
# OSM_UPDATE_FILE - если 1, то обновлять локальный файл osm.pbf до актуального состояния путём наката дельт
|
||||
# OSM_EXPIRE - если 1, то вызывать утилиту render_expired
|
||||
# OSM_METHOD - режим загрузки: osm2pgsql-carto или imposm3-all
|
||||
# OSM_CARTO_VERSION - для режима osm2pgsql-carto - версия osm-carto. Файлы должны быть в /usr/share/mapnik/openstreetmap-carto-ВЕРСИЯ
|
||||
# URL_LATEST - URL последней версии .osm.pbf экспортного файла
|
||||
# URL_UPDATES - URL директории с обновлениями (должна содержать state.txt и дельты)
|
||||
# PG_ENV_OSM_DB - БД PostGIS
|
||||
# PG_ENV_OSM_HOST - хост/сокет БД
|
||||
# PG_ENV_OSM_PORT - порт БД (по умолчанию 5432)
|
||||
# PG_ENV_OSM_USER - пользователь БД
|
||||
# PG_ENV_OSM_PASSWORD - пароль пользователя БД
|
||||
|
||||
use strict;
|
||||
use DBI;
|
||||
|
@ -14,22 +27,19 @@ my $url_updates = $ENV{URL_UPDATES} || 'http://download.geofabrik.de/russia-upda
|
|||
|
||||
if (!$ENV{PG_ENV_OSM_DB})
|
||||
{
|
||||
fatal("OSM database not specified");
|
||||
fatal("Не задана БД OSM");
|
||||
}
|
||||
|
||||
info("Started OSM update for database: $ENV{PG_ENV_OSM_DB}");
|
||||
|
||||
info("Начато обновлением OSM базы данных: $ENV{PG_ENV_OSM_DB}");
|
||||
if ($method ne 'osm2pgsql-carto' && $method ne 'imposm3-all')
|
||||
{
|
||||
fatal("Incorrect OSM update mode: $method");
|
||||
fatal("Некорректный режим обновления: $method (поддерживаются только osm2pgsql-carto и imposm3-all)");
|
||||
}
|
||||
|
||||
-e $dir || mkdir($dir);
|
||||
chdir $dir or fatal("Failed to chdir $dir");
|
||||
chdir $dir or fatal("Директория $dir не существует");
|
||||
eval { run_update() };
|
||||
if ($@)
|
||||
{
|
||||
fatal("$@");
|
||||
fatal("Ошибка кода: $@");
|
||||
}
|
||||
exit(0);
|
||||
|
||||
|
@ -47,7 +57,7 @@ sub run_update
|
|||
{
|
||||
if (!$ENV{OSM_INIT})
|
||||
{
|
||||
fatal("Current OSM version missing, run with OSM_INIT=1 environment variable to initialize");
|
||||
fatal("БД OSM не инициализирована, запустите скрипт с переменной окружения OSM_INIT=1 для инициализации");
|
||||
}
|
||||
$dbh->rollback; # иначе postgresql пишет "statements until the end ignored"
|
||||
# создаём таблицу и оставляем её заблокированной
|
||||
|
@ -56,13 +66,13 @@ sub run_update
|
|||
$dbh->do('CREATE EXTENSION IF NOT EXISTS hstore');
|
||||
# качаем дамп
|
||||
my ($fn) = $url_latest =~ /([^\/]+)$/so;
|
||||
$fn =~ s/^([^\.]+)/$1-$state->{timestamp}/;
|
||||
info("Downloading $url_latest");
|
||||
info("Скачивается файл $url_latest");
|
||||
system("curl -s -C - -f '$url_latest' -o $dir/$fn");
|
||||
if ($? || !-e "$dir/$fn")
|
||||
{
|
||||
fatal("Failed to download $url_latest");
|
||||
fatal("Не удалось скачать файл $url_latest");
|
||||
}
|
||||
system("cp $dir/state.txt $dir/$fn.state.txt");
|
||||
if ($method eq 'osm2pgsql-carto')
|
||||
{
|
||||
init_osm2pgsql($dbh, $state->{timestamp} . ' ' . $state->{sequenceNumber}, "$dir/$fn");
|
||||
|
@ -72,10 +82,12 @@ sub run_update
|
|||
init_imposm3($dbh, $state->{timestamp} . ' ' . $state->{sequenceNumber}, "$dir/$fn");
|
||||
}
|
||||
$dbh->commit;
|
||||
info("OSM database initialized with version: ".$state->{timestamp});
|
||||
info("База данных OSM $ENV{PG_ENV_OSM_DB} инициализирована версией: ".$state->{timestamp});
|
||||
}
|
||||
else
|
||||
{
|
||||
$version = [ split /\s+/, $version ];
|
||||
$version = { timestamp => $version->[0], sequenceNumber => $version->[1] };
|
||||
my $apply = load_geofabrik_deltas($version, $state, $url_updates, $dir);
|
||||
chdir($dir);
|
||||
if ($method eq 'osm2pgsql-carto')
|
||||
|
@ -88,27 +100,35 @@ sub run_update
|
|||
}
|
||||
update_state($dbh, $state);
|
||||
$dbh->commit;
|
||||
info("OSM database updated to version: ".$state->{timestamp});
|
||||
info("База данных OSM $ENV{PG_ENV_OSM_DB} обновлена до версии: ".$state->{timestamp});
|
||||
if ($ENV{OSM_EXPIRE})
|
||||
{
|
||||
system("cat $dir/expire.list | render_expired --map=osm_carto --touch-from=11");
|
||||
system("cat $dir/expire.list | render_expired --map=osm_bright --touch-from=11");
|
||||
}
|
||||
}
|
||||
if ($ENV{OSM_UPDATE_FILE})
|
||||
{
|
||||
apply_deltas_file($url_latest, $url_updates, $dir);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_geofabrik_state
|
||||
{
|
||||
my ($url_updates, $dir) = @_;
|
||||
system("curl -s -f '$url_updates/state.txt' -o $dir/state.txt");
|
||||
if (!-r "$dir/state.txt")
|
||||
if (-r "$dir/state.txt")
|
||||
{
|
||||
fatal("Error downloading $url_updates/state.txt");
|
||||
return parse_geofabrik_state_file("$dir/state.txt");
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal("Не удалось скачать файл $url_updates/state.txt");
|
||||
}
|
||||
|
||||
sub parse_geofabrik_state_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $state;
|
||||
if (open FD, "<$dir/state.txt")
|
||||
if (open FD, "<$file")
|
||||
{
|
||||
local $/ = undef;
|
||||
$state = <FD>;
|
||||
|
@ -116,25 +136,27 @@ sub parse_geofabrik_state
|
|||
$state = { map { (split /\s*=\s*/, $_, 2) } grep { !/^\s*(#.*)?$/so && /=/so } split /\n/, $state };
|
||||
if (!$state->{timestamp} || !$state->{sequenceNumber})
|
||||
{
|
||||
fatal("State file incorrect, should have timestamp=<ISO8601 date> and sequenceNumber=<integer>");
|
||||
fatal("Файл состояния репликации OSM некорректный, должен содержать строки timestamp=<дата_ISO8601> и sequenceNumber=<число>");
|
||||
}
|
||||
$state->{timestamp} =~ s/\\//g;
|
||||
return $state;
|
||||
}
|
||||
}
|
||||
fatal("Error downloading $url_updates/state.txt");
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub load_geofabrik_deltas
|
||||
{
|
||||
my ($version, $state, $url_updates, $dir) = @_;
|
||||
my ($timestamp, $i) = split /\s+/, $version;
|
||||
my ($old_state, $state, $url_updates, $dir) = @_;
|
||||
my $i = $old_state->{sequenceNumber};
|
||||
my $apply = [];
|
||||
while ($i <= $state->{sequenceNumber})
|
||||
while ($i < $state->{sequenceNumber})
|
||||
{
|
||||
my $subdir = sprintf("%03d/%03d", $i / 1000000, ($i / 1000) % 1000);
|
||||
my $fn = sprintf("%03d.osc.gz", $i % 1000);
|
||||
info("Downloading $url_updates/$subdir/$fn");
|
||||
if (!-e "$dir/$subdir/$fn")
|
||||
{
|
||||
info("Скачивается файл дельты $url_updates/$subdir/$fn");
|
||||
}
|
||||
system("mkdir -p $dir/$subdir && curl -C - -s -f '$url_updates/$subdir/$fn' -o $dir/$subdir/$fn");
|
||||
if (-e "$dir/$subdir/$fn")
|
||||
{
|
||||
|
@ -142,7 +164,8 @@ sub load_geofabrik_deltas
|
|||
}
|
||||
else
|
||||
{
|
||||
fatal("Delta not available: $url_updates/$subdir/$fn\n");
|
||||
unlink("$dir/$subdir/$fn") if -e "$dir/$subdir/$fn";
|
||||
fatal("Не удалось скачать файл дельты $url_updates/$subdir/$fn\n");
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
@ -174,7 +197,7 @@ sub init_osm2pgsql
|
|||
my $carto_dir = '/usr/share/mapnik/openstreetmap-carto-'.$ENV{OSM_CARTO_VERSION};
|
||||
if (!$ENV{OSM_CARTO_VERSION})
|
||||
{
|
||||
fatal("osm-carto path not specified");
|
||||
fatal("Не задан путь к osm-carto");
|
||||
}
|
||||
my $cmd =
|
||||
"PGPASSWORD='".$ENV{PG_ENV_OSM_PASSWORD}."' osm2pgsql -I -s -c --hstore".
|
||||
|
@ -185,7 +208,7 @@ sub init_osm2pgsql
|
|||
system($cmd);
|
||||
if ($?)
|
||||
{
|
||||
fatal("$cmd failed");
|
||||
fatal("Загрузка полного дампа с помощью osm2pgsql не удалась");
|
||||
}
|
||||
local $/ = undef;
|
||||
my $fd;
|
||||
|
@ -208,7 +231,7 @@ sub init_imposm3
|
|||
system($cmd);
|
||||
if ($?)
|
||||
{
|
||||
fatal("$cmd failed");
|
||||
fatal("Загрузка полного дампа с помощью imposm3 не удалась");
|
||||
}
|
||||
my $indexes = "SET SEARCH_PATH TO import, public;
|
||||
CREATE INDEX IF NOT EXISTS osm_polygon_area ON osm_polygon (st_area(geometry));
|
||||
|
@ -240,7 +263,7 @@ sub apply_deltas_osm2pgsql
|
|||
system($cmd);
|
||||
if ($?)
|
||||
{
|
||||
fatal("$cmd failed");
|
||||
fatal("Загрузка дельт osm2pgsql не удалась");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +274,7 @@ sub apply_deltas_imposm3
|
|||
my $carto_dir = '/usr/share/mapnik/openstreetmap-carto-'.$ENV{OSM_CARTO_VERSION};
|
||||
if (!$ENV{OSM_CARTO_VERSION})
|
||||
{
|
||||
fatal("osm-carto path not specified");
|
||||
fatal("Не задан путь к osm-carto");
|
||||
}
|
||||
if (@$apply)
|
||||
{
|
||||
|
@ -263,11 +286,31 @@ sub apply_deltas_imposm3
|
|||
system($cmd);
|
||||
if ($?)
|
||||
{
|
||||
fatal("$cmd failed");
|
||||
fatal("Загрузка дельт imposm3 не удалась");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub apply_deltas_file
|
||||
{
|
||||
my ($url_latest, $url_updates, $dir) = @_;
|
||||
my ($full_fn) = $url_latest =~ /([^\/]+)$/so;
|
||||
my $old_state = parse_geofabrik_state_file("$dir/$full_fn.state.txt");
|
||||
my $state = parse_geofabrik_state($url_updates, $dir);
|
||||
my $apply = load_geofabrik_deltas($old_state, $state, $url_updates, $dir);
|
||||
if (@$apply)
|
||||
{
|
||||
my $cmd = "osmconvert $dir/$full_fn '".join("' '", @$apply)."' -o $dir/new-$full_fn";
|
||||
system($cmd);
|
||||
if ($?)
|
||||
{
|
||||
fatal("Обновление локального файла .osm.pbf не удалось");
|
||||
}
|
||||
system("mv $dir/new-$full_fn $dir/$full_fn");
|
||||
system("cp $dir/state.txt $full_fn.state.txt");
|
||||
}
|
||||
}
|
||||
|
||||
sub info
|
||||
{
|
||||
my ($msg) = @_;
|
||||
|
|
Loading…
Reference in New Issue