генерируем все слои на всю территорию охвата данных и храним их все в файловой системе;
генерируем только то, что запросил пользователь, складываем это в кэш.
(Предполагается, что речь идет о территории страны или федерального округа, а не города.)
При ограниченной посещаемости, да еще при просмотре пользователями только населенных областей (а статистика картографических сервисов указывает на очень сильную корреляцию распределения числа запросов и плотности населения), количество тайлов, которые придется сгенерировать, может отличаться в меньшую сторону на порядки.
Дак alacarte генерит тайлы по запросу, точно так же как все остальные. Речь ведь о том что нужно сделать чтобы каждая домохозяйка могла сделать свой стиль для РФ и добавить его на осм.ру.
Относительная простота редактирования стилей у alacarte - есть. Возможностей держать нагрузку по рендерингу всей РФ, я так понимаю - нет. Если есть добровольцы готовые поддерживать определенный стиль/набор стилей по областям РФ (не обязательно прям по областям, можно по долготам поделиться) то можно попытаться что то напридумывать.
tilecache между прочим используется для кэширования чего-то полученного от другого тайлсервера.
mapnik используется повсеместно вовсе не потому что он на глагне. Просто это самый популярный рендерер вообще. Его используют далеко не только в OSM. Он быстр, для него существуют готовые вменяемые решения (SLD не предлагать :)) по управлению стилями, есть простые и эффективные инструменты управления инфраструктурой (mod_tile, renderd, tirex, osm2pgsql), в которых предусмотрены многие вопросы по оптимизации массового сервиса (рендеринг по запросу, hashed directory tree, метатайлы, tile expire и пр.). Нет смысла переходить на что-то ещё, во всяком случае, если на то нет очень веских оснований.
По моим оценкам z1-z13 для всей территории России и до z18 по городам с населением более 100 тыс. человек - это ~360 тыс. метатайлов, или 23 миллиона тайлов. С учётом того, что средний размер метатайла может быть что-то вроде 200-300 кб, я бы заложил минимум 100 Гб под кэш.
Для чего нужен tilecache - я в курсе, упомянул его как элемент связки, а не как решение для визуализации.
По поводу популярности - лично для меня это вопрос открытый.
Нет, но дефолтный 4Кб, а даже в городах тайл занимает 3Кб, а пустой тайл с одной дорогой меньше 1Кб, а их большинство, так что потери на кластер почти 50%.
Поизучал вчера возможности разных программ… Конечно большинство заточено на ubuntu, что для меня чревато “чёрным ящиком”, т.е. одноразово всё это запустить в виртуалке смог, но шаг влево-вправо - проблемы решить не смогу.
В то же время обнаружилось что TileMill имеет встроенный рендер на основе кода мапника, но он сознательно сделан без кеширования т.к. в основном используется для отладки стилей. Сидит по адресу и порту
http://localhost:20008/tile/road-trip/{z}/{x}/{y}.png (италиком выделено название проекта-картостиля в TileMill)
Его тайл-сервер можно также запускать фоном без GUI. Соответственно нужно прикрутить tilecache или что-то подобное, а также настроить подгрузку дифов в PostGIS и проверку необходимости обновления тайлов.
У меня нет. Но зачем тебе, только если ты собираешься рассматривать карту на 18 зуме. На больших масштабах довольно сильно грузит процессор для рендеринга, поэтому вряд ли получится что-то адекватное с RaspberryPi.
Хочется экспериментов с картами, в закрытой сети без доступа к интернету(Отображение разнородной телеком-информации с привязкой к узлам доступа на карте)
Поднимать ради мелких задач мапник, postgis и прочее считаю неразумным.
Ручками “лялюкарту” собрать мне не удалось
К сожалению развитие прекратилось в 2013 году, issues висят годами. Есть несколько досадных недороаботок или багов, которые не позволяют использовать его на полную мощь, хотя и сейчас это достойный инструмент.
AMDmi3, freeExec, akks, Zverik - не могли бы вы довести alaCarte до ума ? Меня при одном взгляде на boost берет оторопь ))
Issues, bugs:
Не подписываются замкнутые мультиполигоны - заливка есть, надписи нет.
Заполнение line паттернами image выровнено по экрану, а не по линии: невозможно рисовать стрелки одностороннего движения, обозначать ЛЭП, а также делать линии асимметричными, например обрывы.
Функция eval не работает для свойства text, и вообще у eval очень ограниченный список поддерживаемых функций от стандарта.
Не поддерживаются class и set. Без них mapcss сильно разрастается т.к. одни и те же условия приходится проверять по нескольку раз (например при анализе surface, smoothness, tracktype и их комбинаций). По поводу set ответил TheMarex, но похоже мы просто не поняли друг друга: я понимаю set как временную переменную для упрощения синтаксиса, а не исправление базы объектов на лету.
Это самые наболевшие проблемы. Еще не хватает макроподстановок типа размера шрифтов, толщины линий - для ретины приходится переделывать размеры и зум. Впрочем этой функции в стандарте MapCSS нет.
Собрал отладочную версию под винду, выяснилось следующее: программа при парсинге mapcss все значения справа от двоеточия трактует как eval вне зависимости пишится eval явно или нет. Когда все правила обработаны, происходит финальное присвоение значений, и вот тут поля text и shield-text трактуются не как остальные - считается что там находится название тега. Вместо того чтобы использовать в стандарте хотя бы макропеременные чтобы отличить название поля от значения, решили сделать так. Итого конструкции
text: name
text: “na . me”
text: eval (concat(“n”, “ame”)
выдают одинаковый результат т.е. это название тега.
Сделал заплатку, чтобы тест трактовался как значение ставлю перед ним underscore.
text: “_name” будет отрендерен как “name”. Костыль, конечно ((
diff --git a/src/server/style.cpp b/src/server/style.cpp
index 4bcf30a..b426f92 100644
--- a/src/server/style.cpp
+++ b/src/server/style.cpp
@@ -159,25 +159,39 @@ void Style::finish(GeoObject* associatedObject, shared_ptr<const Stylesheet> sty
if (this->text.str().size())
{
- // text is not null, so do a tag lookup and display the tag value
- auto entry = associatedObject->getTags().find(this->text, boost::hash<MaybeCachedString>(), CachedComparator());
- if (entry != associatedObject->getTags().end()) {
- this->text = entry->second.str();
+ // text is not null, check raw text or tag
+ if (this->text.str().substr(0, 1) == "_") {
+ // raw text after underscore, not a tag
+ this->text = this->text.str().substr(1);
} else {
- // no tag of that name found. display empty text
- this->text = "";
+ // text is not null, so do a tag lookup and display the tag value
+ auto entry = associatedObject->getTags().find(this->text, boost::hash<MaybeCachedString>(), CachedComparator());
+ if (entry != associatedObject->getTags().end()) {
+ this->text = entry->second.str();
+ }
+ else {
+ // no tag of that name found. display empty text
+ this->text = "";
+ }
}
}
if (this->shield_text.str().size())
{
- // shield_text is not null, so do a tag lookup and display the tag value
- auto entry = associatedObject->getTags().find(this->shield_text, boost::hash<MaybeCachedString>(), CachedComparator());
- if (entry != associatedObject->getTags().end()) {
- this->shield_text = entry->second.str();
- } else {
- // no tag of that name found. display empty text
- this->shield_text = "";
+ // shield_text is not null, check raw text or tag
+ if (this->shield_text.str().substr(0, 1) == "_") {
+ // raw text after underscore, not a tag
+ this->shield_text = this->shield_text.str().substr(1);
+ }
+ else {
+ // shield_text is not null, so do a tag lookup and display the tag value
+ auto entry = associatedObject->getTags().find(this->shield_text, boost::hash<MaybeCachedString>(), CachedComparator());
+ if (entry != associatedObject->getTags().end()) {
+ this->shield_text = entry->second.str();
+ } else {
+ // no tag of that name found. display empty text
+ this->shield_text = "";
+ }
}
}