Alacarte, рендеринг своих карт средствами OSM

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

Я про это и не говорил ничего. Но сравним:

  • генерируем все слои на всю территорию охвата данных и храним их все в файловой системе;
  • генерируем только то, что запросил пользователь, складываем это в кэш.
    (Предполагается, что речь идет о территории страны или федерального округа, а не города.)
    При ограниченной посещаемости, да еще при просмотре пользователями только населенных областей (а статистика картографических сервисов указывает на очень сильную корреляцию распределения числа запросов и плотности населения), количество тайлов, которые придется сгенерировать, может отличаться в меньшую сторону на порядки.

Дак 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 - я в курсе, упомянул его как элемент связки, а не как решение для визуализации.
По поводу популярности - лично для меня это вопрос открытый.

Недавно только графики были, что надо считать не размер тайла, а размер кластера файловой системы.

У месье кластеры размером 300 кб?

На z18 у вас будет очень много пустых клеток, это тоже стоит учитывать.

Нет, но дефолтный 4Кб, а даже в городах тайл занимает 3Кб, а пустой тайл с одной дорогой меньше 1Кб, а их большинство, так что потери на кластер почти 50%.

В городах пустых тайлов явно меньше чем в среднем по больнице.

Городов на всю Россию кот наплакал. В основном или пусто или лес.

Поизучал вчера возможности разных программ… Конечно большинство заточено на ubuntu, что для меня чревато “чёрным ящиком”, т.е. одноразово всё это запустить в виртуалке смог, но шаг влево-вправо - проблемы решить не смогу.

В то же время обнаружилось что TileMill имеет встроенный рендер на основе кода мапника, но он сознательно сделан без кеширования т.к. в основном используется для отладки стилей. Сидит по адресу и порту

http://localhost:20008/tile/road-trip/{z}/{x}/{y}.png (италиком выделено название проекта-картостиля в TileMill)

Его тайл-сервер можно также запускать фоном без GUI. Соответственно нужно прикрутить tilecache или что-то подобное, а также настроить подгрузку дифов в PostGIS и проверку необходимости обновления тайлов.

PS: ещё бы кэш хранить в одном файле…

freeExec
Спасибо, действительно загружает оба ядра на ноутбуке. :up:

А случаем под ARM собрать alacarte кто то не сможет? Интересует под RaspberryPi…
Был бы весьма признателен

У меня нет. Но зачем тебе, только если ты собираешься рассматривать карту на 18 зуме. На больших масштабах довольно сильно грузит процессор для рендеринга, поэтому вряд ли получится что-то адекватное с RaspberryPi.

Хочется экспериментов с картами, в закрытой сети без доступа к интернету(Отображение разнородной телеком-информации с привязкой к узлам доступа на карте)

Поднимать ради мелких задач мапник, postgis и прочее считаю неразумным.
Ручками “лялюкарту” собрать мне не удалось :frowning:

P.S. Mapnik же на малинке запускали…

Замечательный рендер, не требующий танцев с базами, настройками и т.д. Работает быстро, для Windows просто находка.
http://shtosm.ru/all/alacarte/
http://forum.openstreetmap.org/viewtopic.php?pid=329105

К сожалению развитие прекратилось в 2013 году, issues висят годами. Есть несколько досадных недороаботок или багов, которые не позволяют использовать его на полную мощь, хотя и сейчас это достойный инструмент.

AMDmi3, freeExec, akks, Zverik - не могли бы вы довести alaCarte до ума ? Меня при одном взгляде на boost берет оторопь ))

Issues, bugs:

  1. Не подписываются замкнутые мультиполигоны - заливка есть, надписи нет.
  2. Не рисуются иконки в центре area
  3. Заполнение line паттернами image выровнено по экрану, а не по линии: невозможно рисовать стрелки одностороннего движения, обозначать ЛЭП, а также делать линии асимметричными, например обрывы.
  4. Функция eval не работает для свойства text, и вообще у eval очень ограниченный список поддерживаемых функций от стандарта.
  5. Не поддерживаются 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 = "";
+			}
 		}
 	}