создание своего OSM-сервера, как прокси

Начеркал :slight_smile: http://wiki.openstreetmap.org/wiki/User:S-s-s_wiki/%D0%A1%D0%BE%D0%B7%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5_%D0%B8_%D0%BF%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B0_%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D0%BB%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B9_%D0%B1%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_%D0%9E%D0%A1%D0%9C

Спасибо! Надеюсь поможет потом.
Сейчас база есть, мапник рендерится.

Поковырялся, наваял страничку по документации из OpenLayer. Базовую карту (http://labs.metacarta.com/wms/vmap0) через локальный tilecache показывает (basic в конфиге tilecache-a).
Со своей (osm в конфиге tilecache-a) проблемы - показывает только воду. “Мир воды”… :wink:

Причём, если захожу на:
http://osm.rs.int/tilecache/tilecache.cgi/1.0.0/osm/0/0/0.png - вода.
Если же гляжу картинку на файловой системе, которую срендерил мапник в: /opt/osm/mapnik/mapnik/tiles/0/0/0.png

то там весь мир в одной картинке - и суша и океаны…
Почистил кэш tilecache-а (tmp/tilecache) - толку ноль.

Конфигурация tilecache-а:


[cache]
type=Disk
base=/tmp/tilecache

[osm]
type=MapnikLayer
mapfile=/opt/osm/mapnik/mapnik/osm2.xml

[basic]
type=WMS
url=http://labs.metacarta.com/wms/vmap0

По идее, даже если проекция какая-то не та, то базовую (0/0/0.png) картинку-то должен показывать на последнем масштабе, или нет?

К слову, в tilecache-е пришлось в некоторых файлах поменять mapnik на mapnik2. Иначе валилось с ошибкой.

Как создать рабочий конфиг для mapnik2 в EPSG:3857?


./generate_xml.py_def --host localhost --user postgres --dbname gis --symbols ./symbols/ --world_boundaries ../world_boundaries/ --port 5432 --password 'xxxxxx' --epsg='3857'
Usage: generate_xml.py_def [template xml] <output xml> <parameters>

Full help:
 $ generate_xml.py_def -h (or --help for possible options)

Read 'osm.xml' and modify '/inc' files in place, pass dbname and user, accept empty string for other options
 $ generate_xml.py_def --dbname osm --user postgres --accept-none

Read template, save output xml, and pass variables as options
 $ generate_xml.py_def osm.xml my_osm.xml --dbname spain --user postgres --host ''

generate_xml.py_def: error: Sorry only supported projections are: [900913, 4326]

Править generate_xml.py, чтобы поддерживал? Поправил, - при генерации тайлов - падает в корку:


MAPNIK_MAP_FILE="osm.xml" MAPNIK_TILE_DIR="tiles/" ./generate_tiles.py
render_tiles( (-180.0, -90.0, 180.0, 90.0) osm.xml tiles/ 0 5 World )
Ошибка сегментирования

Говорили нужно конвертировать с помощью:


upgrade_map_xml.py osm.xml osm3.xml
Upgrading "osm.xml" to "osm3.xml"...
Ошибка сегментирования

Вопрос: Как заставить mapnik2 генерировать тайлы в проекции EPSG:3857? Это возможно вообще?

generate_xml пользоваться не надо. Сделай чистый чекаут и просто поправь пароль-логин где-то в inc/ - конфиг из OSM SVN сразу готов к бою.

Проекция EPSG:3857 - проекция с долгой историей. 900913 - это она же.

А зачем было исправлять 85-й с чем-то градус на 90? Верни назад, полюса на карте не видно же.

Не трогать ничего лишнего. Оно всё по-дефолту именно на это настроено, в т.ч. на osm.org.

Спасибо!

Хм, так по умолчанию стояло… Выставил 85.

Виноват! Оказывается osm.xml у меня лежал какой-то кривой с неверной проекцией, а я думал, что он переписывается с помощью generate_xml.py…

Однако, взял свежий мапник:


svn info
Path: .
URL: http://svn.openstreetmap.org/applications/rendering/mapnik
Repository Root: http://svn.openstreetmap.org
Repository UUID: b9d5c4c9-76e1-0310-9c85-f3177eceb1e4
Revision: 27140

  1. прописал данные для доступа к базе в:
    ./inc/datasource-settings.xml.inc

  2. Запускаю:


MAPNIK_MAP_FILE="osm.xml" MAPNIK_TILE_DIR="tiles/" ./generate_tiles.py
render_tiles( (-180.0, -90.0, 180.0, 90.0) osm.xml tiles/ 0 5 World )
### Map properties warning: 'bgcolor','minimum_version' are invalid, acceptable values are:
'background-color,background-image,srs,buffer-size,paths-from-xml,minimum-version,font-directory,maximum-extent,base'
### Font properties warning: 'face_name' is invalid, acceptable values are:
'face-name'
Traceback (most recent call last):
  File "./generate_tiles.py", line 214, in <module>
    render_tiles(bbox, mapfile, tile_dir, 0, 5, "World")
  File "./generate_tiles.py", line 135, in render_tiles
    renderer = RenderThread(tile_dir, mapfile, queue, printLock, maxZoom)
  File "./generate_tiles.py", line 64, in __init__
    mapnik.load_map(self.m, mapfile, True)
RuntimeError: Failed to find font face '' in FontSet 'book-fonts' in map 'osm.xml'

osm.xml - тот, что идёт из svn-а, в корне mapnik-a…

Если же всё же сделать, как советовали выше:


upgrade_map_xml.py osm.xml osm2.xml

часть вывода:


Changing face_name to face-name
Changing face_name to face-name
Changing face_name to face-name

После этих манипуляций вроде что-то сгенерировалось и даже показывается в рельсах! :slight_smile:

Товарищи, подскажите такой момент, насчёт баз.

В документации по установке ruby on rails говорится, что нужно создать три базы:

createdb -E UTF8 -O openstreetmap openstreetmap
createdb -E UTF8 -O openstreetmap osm_test
createdb -E UTF8 -O openstreetmap osm

openstreetmap - основная - в неё загружаются пользовательские данные редактирования.
osm_test - тестовая, говорят, что она перезатирается при инициализации - для внутренних нужд?
osm - production - зачем она?

Проинициализировал пустую базу openstreetmap, добавил туда парочку объектов (через josm, который подключается к локальным рельсам).
Теперь задача срендерить с неё слой mapnik-ом. Но мапник хочет базу postgis.

Т.е. данные нужно перегонять из одной базы (openstreetmap) в базу postgis (gis) и потом уже натравливать на неё mapnik?

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

Судя по общей схеме ОСМ - это так
http://wiki.openstreetmap.org/wiki/File:OSM_Components.png

Мое описание выше именно об этом этапе - подготовка данных к рендерингу.

Чувствую, что буду делать аналогично, т.е. раз в неделю на выходных перезаливать базу и рендерить заново подложку ОСМ.

О! Большое спасибо за картинку (и за документацию ещё раз :slight_smile: ). После надо будет наваять полную инструкцию по поднятию своего rails-сервера… Со всеми возможными подводными камнями.

Почему-то generate_tyles.py валились с ошибкой:


render_tiles( (131.980255, 43.098925999999999, 131.985131, 43.102438999999997) osm2.xml tiles/ 10 16 Vladivostok )
Postgis Plugin: SRID warning, using srid=-1
Traceback (most recent call last):
  File "./generate_tiles_vlad.py", line 218, in <module>
    render_tiles(bbox, mapfile, tile_dir, minZoom, maxZoom, "Vladivostok")
  File "./generate_tiles_vlad.py", line 135, in render_tiles
    renderer = RenderThread(tile_dir, mapfile, queue, printLock, maxZoom)
  File "./generate_tiles_vlad.py", line 64, in __init__
    mapnik.load_map(self.m, mapfile, True)
RuntimeError: :
ERROR:  relation "planet_osm_polygon" does not exist
LINE 4:        from planet_osm_polygon
                    ^
Full sql was: 'SELECT * FROM
      (select way,aeroway,amenity,landuse,leisure,man_made,military,"natural",power,tourism,name,highway,
       case when religion in ('christian','jewish') then religion else 'INT-generic'::text end as religion
       from planet_osm_polygon
       where landuse is not null
          or leisure is not null
          or aeroway in ('apron','aerodrome')
          or amenity in ('parking','university','college','school','hospital','kindergarten','grave_yard')
          or military in ('barracks','danger_area')
          or "natural" in ('field','beach','desert','heath','mud','wood','sand','scrub')
          or power in ('station','sub_station','generator')
          or tourism in ('attraction','camp_site','caravan_site','picnic_site','zoo')
          or highway in ('services','rest_area')
       order by z_order,way_area desc
      ) as leisure
       LIMIT 0'
 (encountered during parsing of layer 'landcover' in map 'osm2.xml')

Оказалось, что данные нужно заливать в gis-базу не командой:


osm2pgsql --style /usr/local/share/osm2pgsql/default.style --create --database db-local\
 --username usr-local --prefix planet --slim --cache 2048 --hstore first-dump_api.osm

а с изменённым префиксом:


osm2pgsql --style /usr/local/share/osm2pgsql/default.style --create --database db-local\
 --username usr-local --prefix planet_osm --slim --cache 2048 --hstore first-dump_api.osm

После этого моя одна тестовая точка, добавленная через josm на локальный rails-сервер была отрендерина и показана на карте на rails-сервере.

Правда пока показываю в виде правки строки тайлов для основного слоя Mapnik в /opt/osm/rails/public/openlayers/OpenStreetMap.js:


"http://gpw.rs.int/tilecache/tilecache.cgi/1.0.0/osm/${z}/${x}/${y}.png"

Сейчас осталось разобраться как правильно туда прописать отображение моего отрендеренного слоя, чтобы по галочке он включался и отключался в rails-сервере…

Было бы не плохо…

всё время наступаю на грабли WMS по такой схеме:

Сгенерил свой слой, прописал в rails-сервере ссылку вида:

http://gpw.rs.int/tilecache/tilecache.cgi/1.0.0/drsk/${z}/${x}/${y}.png

Слой показывается. Всё работает. Ссылки вида:

http://gpw.rs.int/tilecache/tilecache.cgi/1.0.0/drsk/13/7098/3006.png

Открываются.

Если же пытаюсь обратиться как к WMS:

http://gpw.rs.int/tilecache/tilecache.cgi?LAYERS=drsk&TRANSPARENT=true&FORMAT=png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=131.923828125,43.06640625,132.01171875,43.154296875&WIDTH=256&HEIGHT=256

То ответ такой:


An error occurred: can't find resolution index for 0.000343. Available resolutions are: 
[156543.03390000001, 78271.516950000005, 39135.758475000002, 19567.879237500001, 9783.9396187500006, 4891.9698093750003, 2445.9849046875001, 1222.9924523437501, 611.49622617187504, 305.74811308593752, 152.87405654296876, 76.43702827148438, 38.21851413574219, 19.109257067871095, 9.5546285339355475, 4.7773142669677737, 2.3886571334838869, 1.1943285667419434, 0.59716428337097172, 0.29858214168548586]

Кусок карты примерно один и тот же. Обращался к wms из тестового примера на OpenLayers.js, при подстановке туда другого слоя (base, который в конфиге tilecache-а ссылается на http://labs.metacarta.com/wms/vmap0 ) - карта отображается.

В гугле (http://osgeo-org.1803224.n2.nabble.com/Configuration-of-TileCache-and-OpenLayers-td1837117.html) нашёл решение:
Нужно вычесть от одной координаты слоя другую (брать из bbox в generate_tiles.py), поделить это на 512 и получим maxResolution. Прописываем bbox и maxResolution в html-ку из которой обращаемся к tilecache-у, а так же прописываем bbox слоя в конфиг tilecache-а для этого слоя.
Попробовал - не получилось.

Вопрос - правильное ли это решение, если да - где я ошибся, если нет - то какое правильное?
Пробовал сгенерить “базовую карту”:


bbox = (-180.0,-85.0, 180.0,85.0)
render_tiles(bbox, mapfile, tile_dir, 0, 5, "World")

Думаю, уж эта-то должна отображаться правильно по-умолчанию - ан нет - та же проблема.

WMS нужен, чтобы отображать эти слои в виде подложки в josm.

Код js в html-ке, для отобраджения базового и моего слоя:



var base_map = new OpenLayers.Layer.WMS( "tilecache", 
"http://gpw.rs.int/tilecache/tilecache.cgi?", 
{ layers: 'basic', 
format: 'png'} );
map.addLayer(base_map);


var tc = new OpenLayers.Layer.WMS( "tilecache", 
"http://gpw.rs.int/tilecache/tilecache.cgi?", 
{ layers: 'drsk', 
transparent: 'true',
format: 'png'} );
map.addLayer(tc);

Конфиг tilecache-а по поводу этих слоёв:


[basic]
type=WMS
url=http://labs.metacarta.com/wms/vmap0
extension=png

[drsk]
type=MapnikLayer
mapfile=/opt/osm/mapnik/mapnik_drsk/mapnik/osm2.xml
spherical_mercator=true
tms_type=google
metatile=yes

Это должно отображаться снаружи?


No query information to decode. QUERY_STRING is set, but empty.

Да, вот, например так:
http://vmap0.tiles.osgeo.org/wms/vmap0?LAYERS=basic&FORMAT=png&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=90,0,180,90&WIDTH=256&HEIGHT=256

Вроде с этим разобрался, нужно было карту создавать в проекции меркаартора:
http://wiki.osgeo.org/wiki/WMS_Tiling_Client_Recommendation


options = OpenLayers.Util.extend({
maxExtent: new OpenLayers.Bounds(-20037508.34,
-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0339,
units: "m",
projection: "EPSG:900913",
transitionEffect: "resize"
}, options);

 var map = new OpenLayers.Map('map', options);

И уж после этого к нему подключать слои wms:


var drsk = new OpenLayers.Layer.WMS( "drsk", 
"http://gpw.rs.int/tilecache/tilecache.cgi?", 
{ layers: 'drsk', 
transparent: 'true', 
format: 'png'} );
map.addLayer(drsk);

Или прямое отображение картинок:


var osm = new OpenLayers.Layer.XYZ(
"osm",
"http://gpw.rs.int/tilecache/tilecache.cgi/1.0.0/osm/${z}/${x}/${y}.png",
{
numZoomLevels: 16, 
sphericalMercator: true
}
);
map.addLayers([osm]);

Вот только опять возникло пара вопросов:

  1. Когда обращаюсь к своим данным как к WMS - tilecache нагружает postgres. Причём не слабо. Зачем? Если же через XYZ - то напрямую и postgres не трогает.
  2. Только для WMS, если поставить параметр (transparent: ‘true’), то он будет подключаться “галочкой” (в интерфейсе) в довесок к слою, который “основной”. Но при этом он полностью закрывает основной слой. Т.е.е если на моём слое всего пара элементов на карте, то при тыканье “галки” - вся карта исчезает и рисуется только мой слой. А надо бы, чтобы он был полупрозрачен и оба слоя отображались одновременно. Это возможно? В примерах на openlayers.org что-то не могу найти…
    Есть вот этот пример:
    http://openlayers.org/dev/examples/all-overlays-google.html
    Но тут как раз с наложением и перекрытием. Т.е. два слоя одновременно не видны, даже если включить оба.

Ага, по части прозрачности нашёл уже:
http://openlayers.org/dev/examples/layer-opacity.html

Теперь всё это дело прикрутить бы к rails-серверу.

Как говорили выше, все изменения нужно добавлять в файл rails/public/openlayers/OpenStreetMap.js
Хорошо, заходим туда, смотрим. Там записи для слоёв. Если поменять источник данных (ссылки на тайлы для какого-либо слоя), то rails-сервер отображает мои тайлы для этого слоя (где меняли). Всё работает, всё нормально.

Но задача как раз создать свои слои, задать их имя, прозрачность и т.д. именно в rails-сервере. Всё то, что может OpenLayers. На тестовом примере (отдельная html-ка с js) я это обкатал - там работает.

Делаю копию класса из исходного (в том же файле: rails/public/openlayers/OpenStreetMap.js)


OpenLayers.Layer.OSM.drsk = OpenLayers.Class(OpenLayers.Layer.OSM, {
    initialize: function(name, options) {
        var url = [
            "http://gpw.rs.int/tilecache/tilecache.cgi/1.0.0/drsk/${z}/${x}/${y}.png"
        ];
        options = OpenLayers.Util.extend({
            numZoomLevels: 18,
            buffer: 0,
            transitionEffect: "resize"
        }, options);
        var newArguments = [name, url, options];
        OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
    },
    
    CLASS_NAME: "OpenLayers.Layer.OSM.drsk"
});

Дописываю в конец файла, обновляю страничку rails-сервера - ноль эмоций. Никаких новых вкладочек слоёв не появилось… Судя по всему ещё нужно куда-то прописывать. По всей ветке мне сказали только про этот файл. grep-ом погрепал весь rails-сервер - куча упоминаний про тот же osmarender. Попереправлял и там - не помогло…

Как правильно это делать? Должно же быть просто как-то (без переписывания кода rails-сервера).

Думаю, что без ковыряния кода rails-сервера и добавления в него своего класса ничего не получится. Видимо rails-сервер не предназначен для использования в нем произвольных , собственных слоев.
Для отображения своих слоев-классов нужно использовать обычный tile-сервер c OpenLayers, а rails-сервер только для ввода данных. Ну или подменять один из классов rails-сервера.
Все имхо.

Более тщательно почитал документацию по TileCache и выяснил, что:

This TileCache client supports multiple different rendering backends. Each rendering backend also supports the ability to draw ‘metatiles’, where a large tile is rendered, and then chopped into smaller tiles using the Python Imaging library.

MapServer -- render a tile using Python mapscript.
Mapnik -- render a tile using the mapnik Python bindings.
Cascading WMS -- fetch a tile from a remote WMS service. (Uses urllib to fetch tiles.)

Оказывается, что он не просто отдаёт тайлы, которые до этого нагенерировал мапник, а рендерит тайлы “на лету”, может быть даже через вызов мапника, складывает их себе в кэш и потом раздаёт по сети тем, кто спрашивает. Но в результате получается это несколько медленно. При масштабировании странички на сервере ворох процессов postgres, всё тормозит и в конечном счёте карта не отрисовывается. А тем временем тайлы у меня уже сгенерированы скриптом лежат в директории и никому (tilecache) они не нужны.

Как правильно отдавать статически сгенерированные тайлы? Mod_tile вроде так же работает как TileCache… Или нет?

Начал писать документацию:
http://wiki.openstreetmap.org/wiki/Создание_локального_OSM-сервера

По части работы сервера ещё возник вопрос по заливке треков. В логи сыпется следующиее:


[2011-12-27 13:23:25.471812 #4304] Rendered layouts/_inbox (11.2ms)
[2011-12-27 13:23:25.484420 #4304] Completed in 1276ms (View: 47, DB: 7) | 200 OK [osm.rs.int/user/semenov/traces]
[2011-12-27 13:25:05.134008 #13432]   Message: getpresets
[2011-12-27 13:25:05.492383 #13432] GPX Import daemon wake @ Tue Dec 27 13:25:05 +1100 2011.
[2011-12-27 13:25:05.502572 #13432]   ^[[4;36;1mSQL (0.2ms)^[[0m   ^[[0;1mSET client_min_messages TO 'panic'^[[0m
[2011-12-27 13:25:05.502914 #13432]   ^[[4;35;1mSQL (0.2ms)^[[0m   ^[[0mSET standard_conforming_strings = on^[[0m
[2011-12-27 13:25:05.503245 #13432]   ^[[4;36;1mSQL (0.2ms)^[[0m   ^[[0;1mSET client_min_messages TO 'notice'^[[0m
[2011-12-27 13:25:05.506491 #13432]   ^[[4;35;1mTrace Load (2.6ms)^[[0m   ^[[0mSELECT * FROM "gpx_files" WHERE ("gpx_files"."inserted" = 'f' AND "gpx_files"."visible" = 't') ORDER BY id^[[0m
[2011-12-27 13:25:05.516928 #13432]   ^[[4;36;1mUser Load (1.2ms)^[[0m   ^[[0;1mSELECT * FROM "users" WHERE ("users"."id" = 1) ^[[0m
[2011-12-27 13:25:05.521183 #13432] GPX Import importing 05.gpx (4) from semenov@rsprim.ru
[2011-12-27 13:25:05.650165 #13432]   ^[[4;35;1mTracepoint Load (0.8ms)^[[0m   ^[[0mSELECT * FROM "gps_points" WHERE (gpx_id = 4) LIMIT 1^[[0m
[2011-12-27 13:25:05.671793 #13432]   ^[[4;36;1mSQL (0.3ms)^[[0m   ^[[0;1mBEGIN^[[0m
[2011-12-27 13:25:05.673946 #13432]   ^[[4;35;1mTrace Load (0.6ms)^[[0m   ^[[0mSELECT * FROM "gpx_files" WHERE ("gpx_files"."id" = 4) ^[[0m
[2011-12-27 13:25:05.693795 #13432]   ^[[4;36;1mSQL (0.0ms)^[[0m   ^[[0;1mPGError: ERROR: column "id" does not exist
LINE 1: ....000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"
 ^
: INSERT INTO "gps_points" ("latitude", "gpx_id", "timestamp", "altitude", "tile", "longitude", "trackid") VALUES(431105060, 4, '2011-10-28 22:28:03.000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"^[[0m
[2011-12-27 13:25:05.694364 #13432]   ^[[4;35;1mSQL (0.2ms)^[[0m   ^[[0mROLLBACK^[[0m
[2011-12-27 13:25:05.694599 #13432] PGError: ERROR:  column "id" does not exist
LINE 1: ....000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"
                                                                   ^
: INSERT INTO "gps_points" ("latitude", "gpx_id", "timestamp", "altitude", "tile", "longitude", "trackid") VALUES(431105060, 4, '2011-10-28 22:28:03.000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"

Ну и шлётся письмо вида:


Subject: [OpenStreetMap] GPX Import failure^M
Mime-Version: 1.0^M
Content-Type: text/plain; charset=utf-8^M
Auto-Submitted: auto-generated^M
^M
Привет,

Это выглядит как ваш файл GPX

  05.gpx

с описанием

  комета

и без меток.

сбой импорта. Произошла ошибка:

  PGError: ERROR:  column "id" does not exist
LINE 1: ....000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"
                                                                   ^
: INSERT INTO "gps_points" ("latitude", "gpx_id", "timestamp", "altitude", "tile", "longitude", "trackid") VALUES(431105060, 4, '2011-10-28 22:28:03.000000', -39.941, 3891507807, 1319433050, 0) RETURNING "id"

В результате gpx не импортируется rails-сервером.

И ещё вопрос. Potlach2 не сохраняет правку - тупит на Autorization Requered. Я так понимаю он хочет авторизоваться по OAuth. То ли сам Potlach2 надо зарегистрировать, сказав по какому он адресу работает, то ли пользователи должны иметь учётку OAuth вне локальной сети - непонятно.

В Rails Port для третьей версии rails поменялся формат базы данных - в частности, названия полей id. Если у тебя rails2, нужно использоваться осмозис 0.39, иначе - 0.40.

Потлатч нужно зарегистрировать, зайдя на сайте в свои настройки OAuth и тыкнув в “Зарегистрировать ваше приложение”.