Русифікація та мультимовність карт OpenStreetMap

Займаючись розробкою веб-карток, що використовують даніOpenStreetMap, часто виникає питання про те, як показувати карти з коректними українськими назвами. Ця проблема не виникає, якщо ваші карти показують виключно Україну. Однак, якщо ви подивіться, наприклад, карту Китаю, то вам навряд чи сподобається така велика кількість ієрогліфів, а марні спроби знайти Пекін на такій карті, швидше за все, не увінчаються успіхом.

мультимовність

Відомо, що волелюбний проектOpenStreetMapдозволяє зберігати назви географічних об'єктів різними мовами. Для цього використовуються спеціальні теги типуname:ru,name:enабоname:es, і що найголовніше, вони заповнюються учасникамиOpenStreetMap. Звичайно, найбільш докладні написи створюють користувачі тією мовою, якою вони говорять: в Україні — українською, в Китаї — китайською, в африканських країнах — місцевими мовами. Шансів, що якась вуличка в Нігерії матиме український переклад, мало, але все ж таки основні географічні об'єкти (країни, міста, річки тощо) мають переклади. Цієї невеликої картографічної інформації буває цілком достатньо, щоб українськомовний користувач відкрив, наприклад, карту Китаю та знайшов на ній основні назви. Таким чином, ваш ресурс стане більш доброзичливим для користувача. Якщо поставити собі за мету знайти тлумачну інструкцію, як використовувати ці теги перекладів на власних веб-картах, то в усьому просторі Рунета або навіть Інтернету знайдеться лише розрізнена інформація про різні аспекти питання локалізації веб-картокOpenStreetMap, але "коробкової" інструкції ви навряд чи знайдете. З одного боку, ця проблема є не найскладнішим архітектурним питанням, т.к. технологія розроблена в рамкахсамого проектуOpenStreetMap. Але з іншого боку, у завершених проектах локалізованих веб-карток, наприклад, у відомому Ростелекомівському Супутнику, завдання локалізації було вирішено, а проблеми, з якими зіткнулися розробники і те, як їх вдалося вирішити, залишаються неозвученими IT-громадськістю.

мультимовність

Існують навіть проекти веб-карток з підтримкою багатомовності, але вони не доведені до логічного, доброзичливого користувача кінця.

русифікація

1. Отримуємо векторні даніOpenStreetMap

Ці дані ми імпортуватимемо (за допомогою утиліти osm2pgsql) в базу даних Postgresql, а потім пакет рендерингу Mapnik буде генерувати растрові тайли.

Отже, завантажуємо карту в заданому регіоні у форматі XML (OSM-файл) або в стиснутому бінарному форматі PBF з одного із дзеркалOpenStreetMap. Файл планети можна завантажити командами:

Вам слід пам'ятати, що ці дані займають значний обсяг. Наприклад, файл, що містить векторні дані на всю планету Planet.osm в стиснутому форматі OSM XML займає більше 1ТБ, у форматі XML, стисненому bz2, займає 41.8ГБ, а в бінарному форматі PBF 18.1ГБ. Всі ці формати зберігають ті самі дані. Природно, якщо вам потрібен лише конкретний регіон, а не вся планета, то ці цифри будуть значно меншими, але пропорції обсягів даних у форматах, OSM XML, OSM XML, стиснутому bz2, та у форматі PBF залишаться тими ж. Вам слід мати на увазі, що перед імпортом у Postgresql векторні дані у форматі OSM XML, стиснутому BZ2, і в бінарному форматі PBF будуть попередньо оброблятися (розпаковуватися, парситися), що збільшить час імпорту завантаженого файлу в базу даних Postgresql. Так, на моїй чотириядерній машині Core i5 з 16ГБ ОЗП, 2ТБ HDD (Ubuntu 14.04 64x) імпорт Planet.osm.pbf зайняв 2Тижня. Імпорт аналогічного файлу Planet.osm.bz2 зайняв набагато менше часу. За моїми власними відчуттями, утиліта osm2pgsql вимоглива до обсягу ОЗУ (для оптимального управління пам'яттю почитайте про можливості ключів --cache і --cache-strategy утиліти osm2pgsql), частоту і кількість ядер процесора (у момент парсингу файлу, для управління завантаженням ядер процесора ключ --number-processes утиліти osm2pgsql), а також до швидкості роботи жорсткого диска (у момент вставки даних та створення індексів у Postgresql, для оптимізації див. ключ --disable-parallel-indexing утиліти osm2pgsql). Якщо у вас SSD, то імпорт даних до бази Postgresql пройде значно швидше.

Ми з метою цієї статті використовувати регіон Китаю, т.к. він за умовчанням не русифікований і має відносно невеликий розмір, що зручно на етапі налагодження технології. Файли векторних даних Китаю можна завантажити із сайту проекту geofabrik.de командою:

2. Актуалізуємо отримані векторні даніOpenStreetMap

Справа в тому, що за час, який минув з моменту упаковки файлу даних до моменту розгортання його на вашій машині, на OpenStreetMap могли бути внесені зміни. Тому перед імпортом ми актуалізуємо файл даних командою osmupdate з пакету osmcutils:

Якщо ваш OSM-файл не містить позначку часу (timestamp), то швидше за все утиліта osmupdate поверне помилку. В цьому випадку (якщо ви знаєте timestamp вашого файлу - іноді публікується на сторінці завантаження файлу) треба запустити команду в наступному форматі:

Утиліта osmupdate самостійно завантажує diff-файл і застосовує його до файлу, вказаному в першому аргументі команди виклику. Не рекомендується запускати osmupdate утиліту з великими файлами у форматі OSM XML (наприклад,planet-latest.osm.bz2), т.к. необхідна попередня обробка файлу утилітою osmconvert з того ж пакета osmcutils, а утиліта osmupdate з отриманим конвертованим файлом буде працювати кілька днів. Для великих файлів рекомендується використовувати формат PBF. Але слід мати на увазі, що імпорт такого файлу в Postgresql буде займати більше часу, ніж імпорт файлу OSM XML. Так би мовити, палиця з двома кінцями. Особисто завжди вибираю формат PBF.

3. Конфігуруємо підтримку потрібних мов у налаштуваннях утиліти osm2pgsql

За промовчанням у файлі стилів /usr/share/osm2pgsql/osm2pgsql/default.style не встановлена ​​підтримка будь-яких мов. Для написів на карті використовується тегname, який задається у файлі /usr/share/osm2pgsql/osm2pgsql/default.style рядком:

Допишемо після неї підтримку, наприклад, української, англійської та іспанської мов:

Ці три рядки скажуть утиліті osm2pgsql імпортувати також з PBF файлу ще значення тегівname:ru,name:en,name:se. Інші локалізовані імена будуть проігноровані.

4. Створюємо базу даних Postgresql для зберігання векторних даних OpenStreetMap

Попередньо необхідно налаштувати trust-автентифікацію (щоб не вводити пароль, в рамках цієї статті не потрібно) і створити необхідних користувачів БД (див. інструкцію). Ми в рамках цієї статті обмежимося trust-автентифікацією та стандартним користувачем postgres. Отже, створюємо БД, наприклад, china і підключаємо до неї необхідні розширення:

5. Імпортуємо векторні дані до бази даних Postgresql

Імпорт здійснюється утилітою osm2pgsql. Опис ключів утиліти можна знайти у довідці з утиліти. Деякі пояснюючі відомості наводяться на англомовномуресурсі.

Ключ --drop дозволяє скоротити займаний базою даних дисковий простір, жертвуючи тим самим можливістю згодом оновлювати дані БД зі свіжих файлів PBF або OSM XML. У Китаї обсяг бази даних зменшився з близько 500МБ до 92МБ. Щоб подивитися, який розмір займає база даних, введіть команду в консолі psql, підключеної до будь-якої існуючої бази даних:

6. Створюємо уявлення у БД для відображення перекладених географічних назв.

Скориставшись інструкцією, створимо кілька уявлень SQL. Для генерації «українських» тайлів (тайлів, що містять українські підписи) використовуватимемо префікс china_ru, для генерації «англійських» тайлів – china_en, для генерації «іспанських» тайлів – china_es. Наведемо нижче SQL скрипт створення SQL-уявлень для генерації лише «українських» тайлів. З SQL-уявленнями для генерації «англійських» та «іспанських» тайлів шановний читач, гадаю, розбереться сам, взявши за основу «українські» VIEW.

7. Встановлюємо скрипти від OpenStreetMap для створення тайлів

Нехай для зберігання всіх необхідних скриптів Mapnik ми вибрали директорію /home/osm/mapnik. Викачаємо в неї скрипти від OpenStreetMap для генерації тайлів, викачаємо туди ж шейпи (shape-файли) світу, які використовуються для спрощення генерації тайлів на дрібних масштабах, і створимо XML файли стилів Mapnik'а для приєднання до БД:

Далі нам потрібно створити 3 файли стилів рендерингу тайлів, відповідно, для українських, англійських та іспанських підписів географічних об'єктів. Для цього встановимо спеціальну змінну системного оточення MAPNIK_PREFIX, яка дозволяє встановити префікс таблиць векторних даних у базі даних Postgres і яку прочитає скрипт /home/osm/mapnik/generate_xml.py тапідставить у псевдо-запити до БД.

Ці команди створять 3 спеціальні стилі для рендерингу тайлів, що дозволяють зчитувати дані для рендерингу з потрібних нам уявлень української, англійської чи іспанської мов.

8. Позначимо в скрипті генерації тайлів область Китаю для генерації тайлів

Знаходимо у скрипті /home/osm/mapnik/generate_tiles_multiprocess.py такі рядки:

Після цих рядків напишемо:

Це дозволить згенерувати тайли Китаю з 6-го по 15-ий масштаб, що містять підписи необхідною нам мовою. Інструкція exit() дозволяє відмовитися від подальшого рендерингу областей, прописаних за умовчанням у скрипті /home/osm/mapnik/generate_tiles_multiprocess.py (Muenchen, Muenchen+, Muenchen++, Nuernberg, Karlsruhe, Karlsruhe+, Augsburg, Augs. Існує ще скрипт /home/osm/mapnik/generate_tiles.py, який запускає процес рендерингу в одному потоці. Але ми його використовуватимемо, т.к. за наявності кількох ядер процесора скрипт /home/osm/mapnik/generate_tiles_multiprocess.py у загальному випадку відпрацює швидше.

9. Згенеруємо тайли для обраних локалізацій

Нам необхідно створити директорії, куди Mapnik складатиме згенеровані тайли:

Генерацію тайлів ми повинні запустити тричі, змінюючи значення змінних системного оточення MAPNIK_MAP_FILE та MAPNIK_TILE_DIR. Скрипт прочитає ці змінні та передасть їх Mapnik'у для налаштування рендерингу тайлів:

10. Відобразимо тайли на веб-картці

Для цього створимо найпростішу html-сторінку, в якій підключимо створені тайлові сховища. Файл сторінки слід покласти поруч із директорією згенерованих тайлів /home/osm/mapnik/tiles. Для відображення веб-карток будемо використовувати javascript-фреймворк LeafletJS:

Ця сторінка буде виконуватися локально. У правому верхньому куті має бути доступний контрол, що дозволяє вибрати джерело тайлів. українська, англійська та іспанська версії карт виглядатимуть так:

русифікація
карт
русифікація

11. Рендеринг тайлів «на льоту»

Примітки

А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»