Раскрасим домики

Oct 06, 2014 04:04

Итак, после предыдущих упражнений здания на нашей карте обзавелись номерами и высотой. Что дальше? Дальше можно, например, раскрасить здания в разные цвета. Можно раскрасить дома в зависимости от основного их предназначения (то есть, в зависимости от содержимого тэгов 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%);
Результат:


http://shoorick.ru/2014/10/06/building-color/

osm, ЮУрГУ, карта, дом, work, цвет, tilemill

Previous post Next post
Up