Итак, после предыдущих упражнений здания на нашей карте обзавелись номерами и высотой. Что дальше? Дальше можно, например, раскрасить здания в разные цвета. Можно раскрасить дома в зависимости от основного их предназначения (то есть, в зависимости от содержимого тэгов amenity
и building
). Можно — в зависимости от принадлежности здания.
Когда-то на сайте нашего университета располагалась схема студенческого городка, на которой были здания четырёх разных цветов: общежития, учебные корпуса, прочие здания студгородка, а также посторонние здания, в студгородок не входящие. То есть, на той схеме здания выделялись и по предназначению, и по принадлежности.
Достичь подобного результат с картами OpenStreetMap, рисуемыми через библиотеку Leaflet, можно разными путями: можно, взяв какую-либо карту, не трогать её растровый слой, оставить его без изменений, добавив свой векторный слой, куда нанести контуры зданий. Пример — usjeans.ru/map. Другой подход — сделать собственный растровый слой, на котором сразу и отметить необходимое. Так как предыдущие эксперименты касались как раз собственного растрового слоя — продолжим опыты в том же направлении.
Отметить принадлежность зданий в OpenStreetMap можно разными путями: первый, очевидный — задать у каждого нужного нам здания какой-нибудь новый тэг. Тэг может быть практически любым — даже при существующих ограничениях на имена можно придумать что-нибудь. То множество тэгов, что применяется в OSM — результат не жёсткого диктата разработчиков, а договорённости сообщества участников и множество это легко расширяемо. Другой путь, который мне представляется более верным — создать отношение. Для группировки объектов, представляющих собой что-то общее, предназначено отношение с типом site. Как выяснилось, нужное мне отношение уже́ существовало — надо было лишь проверить его корректность и внести необходимые изменения (например, добавить здания, в отношение не попавшие).
На следующем этапе, импорте данных, выяснилось, что в imposm не предусмотрен способ сохранить в базе данных информацию о принадлежности к отношению. Во всяком случае, в документации он не описан. Не беда — эту информацию можно внести и после импорта, напрямую обратившись к базе данных. Для хранения информации о принадлежности нужно создать дополнительное поле. Так как нам нужен только признак принадлежности здания конкретному отношению, достаточно будет типа Bool
. После всех изменений описание сопоставления данных для зданий в файле imposm-mapping.py стало выглядеть так:
buildings = Polygons(
name = 'buildings',
fields = (
('area', PseudoArea()),
('addr:housenumber',String()),
('building:levels',Integer()),
('height',Integer()),
('belongs_to_susu',Bool()),
),
mapping = {
'building': (
'__any__',
),
'railway': (
'station',
),
'aeroway': (
'terminal',
),
}
)
Выставить флаг принадлежности можно выполнением SQL-запроса
UPDATE osm_buildings
SET belongs_to_susu=1
WHERE osm_id IN (список_id, через запятую);
Чтоб не перечислять объекты вручную, был написан перловый скрипт. Попутно выяснилось, что, несмотря на то, что отношение может в себе содержать другие отношения, нет смысла устраивать рекурсивный обход: в поле osm_buildings.osm_id
хранится первый попавшийся номер: он может быть как номером линии (для большинства зданий), так и номером отношения.
Задача определения роли здания после всех предыдущих манипуляций кажется не такой уж и сложной: во-первых, тип здания (точнее, его предназначение) может хранится в тэге building
— его содержимое при импорте попадает в поле osm_buildings.type
. Среди допустимых типов есть и dormitory
— общежития (кстати, не надо путать с tourism:hostel
— это совсем разные тэги). Тип «учебные корпуса» (например, academic_building) среди часто применяемых не встречается — есть лишь university, который не совсем подходит: университет — это не только учебные корпуса. Можно, конечно, прямо у самих зданий указывать building=academic
, но мне более правильным показался вариант указания роли здания внутри отношения — там и поле для роли есть, и оно не используется совсем. Больше шансов, что данные спокойно сохранятся именно тогда, когда они лежат внутри отношения. А вот в базу данных роль вносится в поле osm_buildings.type
:
UPDATE osm_buildings
SET type='academic'
WHERE osm_id IN (список_id, через, запятую);
Как и прежде, для упрощения назначения ролей, написан ещё один перловый скрипт.
Стилевые правила для зданий (в OSM Bright он лежат в файле base.mss) начинаются так:
#buildings[zoom>=12] {
polygon-fill:@building;
// Our buildings
[belongs_to_susu=1] {
polygon-fill: @susu_building;
[type='dormitory'] {
polygon-fill: @susu_dormitory;
}
[type='academic'] {
polygon-fill: @susu_academic;
}
}
Определение цветов @susu_building
, @susu_dormitory
, @susu_academic
добавлено в файл palette.mss — там для них самое подходящее место.
@susu_building: saturate(darken(@building, 15%), 10);
@susu_dormitory: mix(@susu_building, #f60, 95%);
@susu_academic: mix(@susu_building, #06f, 93%);
Раскрасим домики: 2 комментария
Вы должны авторизоваться чтобы опубликовать комментарий.