Продолжаем эксперименты с обработкой карт напильником. В прошлый раз удалось добавить на карту номера домов — сегодня попытаемся сделать дома чуть выше.
С одной стороны в CartoCSS есть свойство building-height
, описывающее «высоту» зданий — это видно на крупных масштабах (от 17). В OSM Bright величина building-height
постоянна, что даёт на карте здания одинаковой высоты.
С другой стороны, в OpenStreetMap можно хранить данные о высоте различных зданий с сооружений: для этого предназначены тэги height
(высота, по умолчанию в метрах) и building:levels
(количество этажей). И эти, взятые из OSM, сведения о высоте либо числе этажей вполне можно использовать для building-height
— там можно указывать не только числа, но и выражения.
Задача по добавлению поля с высотами в PostGIS аналогична предыдущей — добавлению номеров домов. Надо добавить в imposm-mapping.py пару полей — building:levels
и height
типа Integer
. Я не нашёл способ, как сразу, на этапе импорта данных, выбирать нужное поле, то у которого есть хоть какое-то значение — это не страшно, можно выбрать позже.
Аналогично предыдущей выполняется и задача добавления данных в TileMill: надо добавить новые поля в SQL-запрос в настройках слоя #buildings.
Остаётся последнее — написать подходящее выражение для высоты. В отличие от использования данных в подписях, где имя поля надо было заключить и в квадратные скобки, и в кавычки, здесь, при вычислении выражений, кавычки не нужны — нужны лишь квадратные скобки:
building-height: 1 + [building:levels];
Как выбрать одно из двух полей? В выражении нельзя использовать операцию ||
— можно лишь or
, но она в качестве результата выдаёт true
либо false
. Можно сделать так: сначала указать высоту, основываясь на приблизительном источнике (на числе этажей), а затем, при наличии более точного (собственно, высоты), взять данные с него. В CartoCSS, как и в обычном CSS, при одинаковом приоритете правил срабатывает то, что было объявлено последним.
Правила для указания высоты зданий на карте будут выглядеть так:
building-height: 1 + [building:levels];
[height>0] {
building-height: 1 + [height] / 3;
}
Кроме того, лучше передвинуть слой зданий #buildings повыше, чтоб здания располагались над дорогами.
Результат:
В следующий раз мы рассмотрим способ раскраски зданий в разные цвета.