QGIS и тайловый экспорт
Несколько лет я занимаюсь рисовкой и поддержанием в актуальном состоянии схем-хребтовок двух горных районов. Джунгарского алатау и Центрального Тянь-Шаня.
Изначально я все рисовал в программе Ocad. Это специльная программа для рисования карт спортивного ориентирования. Проект был разбит на десятки листов. Потом эти листы экспортировались в картинки, сшивались и разрезались на тайлы. Тайлы загружались на ftp.
Вот пример того, что получается в QGis
nakarte.me/#m=13/41.94628/77.57910&l=O/Mt
А вот как было в Ocad
nakarte.me/#m=14/44.89276/79.41021&l=O/Mt
И вот однажды я встретил QGIS.
Программа меня впечатлила. Неплохой рендерер. Не такой выразительный как в OCAD, но качество меня устроило. Возможность работать напрямую с геоданными. Возможность работать со всем проектом целиком, не разбивая его на куски.
Все это побудило перенести весь проект на QGIS.
Но теперь я немного об этом жалею.
Рендерер QGIS не приспособлен для генерации тайлов.
Конечно, есть два плагина QTiles и QMetaTiles для QGIS 2. Я их адаптировал и для QGIS 3.
Расскажу подробнее о неисправимых косяках, которые мешают генерации тайловых карт в QGIS.
Экспорт сделан с помощью плагина QTiles
Косяк №1. Когда рендерер вычисляет какие объекты попадают в его область видимости (в QGIS Это называется canvas), то он не учитывает размер символов объектов.
Пример 1а. Точечный объект
Как видите, значок вершины оказался обрезанным. На нижнем тайле рендерер его вывел, а на верхнем — нет. Потому что центр вершины не попал в границы тайла.
Пример 1 б. Линейный объект
Толстая линия проходит рядом с границей тайла. На нижний тайл она попала частично. На верхний тайл вообще не попала.
Линия не обязательно должна проходить по границе тайлов. Еще может быть вот такой артефакт
Косяк №2. Расстановка надписей.
Пример 2а. Короткая надпись на линейном объекте
Рендерер вывел название на каждом тайле.
Пример 2 б. Длинная надпись на линейном объекте
Z15
Z16
На Z15 надпись есть, потому что она целиком влезает в границы тайла.
На Z16 надписей уже нет, потому что длинная надпись не влезает в границы тайла.
Представьте, что вы хотите нарисовать карту мира, а на ней на весь континент большими буквами написать «ЕВРАЗИЯ». Ничего не выйдет. Надпись будет появляться только на тех зумах, где она помещается в тайл целиком.
Пример 2в. Надпись на точечном объекте
Я включил опцию «Show partial labels»
Z16
Z15
На Z16 рендерер показывает только часть надписи, влезающую в тайл. При рендеренге соседнего тайла, он, кончено, про нее забывает.
Если опцию «Show partial labels» выключить, то на Z16 вообще не будет надписи.
С указанными проблемами призваны бороться два метода
1. Метаталинг
2. Буфферные зоны
Метатайлинг.
Рендерится не каждый тайл по отдельности, а группа в несколько тайлов. Скажем, 4×4, а потом разрезается на меньшие кусочки.
Буфферные зоны
Рендерится область большая, чем тайл или метатайл, а потом из нее вырезается нужный кусок.
Оба метода не исправляют вышеуказанные косяки, а сдвигают их на несколько уровней зума ниже. Те же самые косяки проявляются уже на на границах тайлов, а на границах метатайлов или буфферных зон.
Пример 2 г. Точечный объект
Делаю экспорт плагином QMetaTiles. Размер метатайла 2×2. Это значит, что рендерится область в 2×2 тайла, а потом нарезается на куски.
Z16
Действительно. Надпись теперь не обрезается, потому что целиком влезает в область 2×2 тайла. Но на границе метатайла обрезался сам объект. То же будет и с линейным объектом.
Проблема сдвинулась на один уровень зума ниже.
Косяк №3. Скачущие надписи
Пример 3а
Расстановщик каждый раз выбирает наиболее выгодную позицию для очередной надписи. Причем, расположение надписей зависит от положения canvas. Сдвиньте его на пару миллиметров, и все надписи будут расположены совершенно иначе.
Это значит, что при рендеринге одного метатайла и буферной зоны вокруг него надпись может быть в одном места, а при рендеринге соседнего метатайла — совершенно в другом.
Я делаю экспорт куска карты в тайлы. Надписи занимают один порядок.
Затем я немного сдвигаю canvas и делаю опять экспорт. Надписи уже занимают совершенно другой порядок. При этом появляются вот такие артефакты.
Что же с этим всем делать?
Метатайлинг и буфферные области не решают вышеописаныне проблемы, а отодвигают их на меньшие уровни зума.
1. Когда рендерер вычисляет какие объекты он должен нарисовать, то он должен учитывать не только геоданные объектов, но их их символику.
Например, для всех объектов рендерер должен хранить BBOX, который объект занимает после индивидуального рендеринга. При рендеринге сцены, нужно учитывать пересечение canvas с индивидуальным BBOXами отрендеренных объектов.
При этом желательно, чтобы BBOX вмещал в себя еще и надписи, привязанные к объекту.
2. Расположение надписей не должно зависеть от расположения canvas. Тогда при частичном экспорте фрагменты надписей будут хорошо сшиваться. Отпадет необходимость в метатайлинге и буфферных зонах.
К сожалению, на данный момент экспорт тайлов из QGIs просто ужасен, и когда он будет исправлен не ясно.
Может, есть тут кто-то, принимающий участие в разработке QGis?