Никита Славин
Картограф
лонгрид про создание how-old-is-this.house
ИДЕЯ
BIG TIME BCN: визуально впечатляющий проект про застройку Барселоны
Примерно из ниоткуда возникает идея сделать прекрасную складную карту Петербурга, показывающую возраст домов, их архитектурный стиль, и на которой будут выделены здания - яркие представители стиля.

В памяти есть какие-то онлайн-проекты.
Беглый поиск дает много примеров из разных городов: Портланд, Рейкьявик, Нью-Йорк: Бруклин, Манхеттен, Барселона, Любляна, Львов, и даже проект масштаба страны, - Нидерланды.
Про Петербург тоже кое-что есть: например, отличные данные на Петроградку: «Ретроспектива застройки Петербурга» и проект Делового Петербурга: «Как застраивался Петербург: история строительства города за 68 секунд».

Цель — бумажная карта, к идее сделать веб-интерфейс приду в процессе. Начинаю искать сырые данные.
ДАННЫЕ
Проекты Павла Суворова про Петроградку и Делового Петербурга ссылаются на «Технико-экономические паспорта многоквартирных домов» — это табличка на двадцать две с лишним тысячи домов, с разными характеристиками. Как я понял, она появилась благодаря программе взносов на капитальный ремонт. В таблице интерес представляют адрес и год постройки, географических координат, увы нет.

«Паспорта» лежат на портале «Открытые данные Петербурга». На нем же есть раздел «Карта» и, если хорошо искать, или у тебя знающие друзья, в разделе прочее есть слой «Объектно-адресная система Санкт-Петербурга». В нем прекрасно детализированная геометрия всех объектов, имеющих адрес в Петербурге, в атрибутах помимо названия объекта и адреса, регулярно встречается год постройки. Всего сто двадцать пять тысяч адресов, и сорок одно тысячa дат. Прекрасно подходит, только нужно избавиться от набережных, разъездных путей и прочего, что не является зданиями.

Но не каждое здание в Петербурге имеет адрес, зато почти каждое — отрисовано соавторами карты OpenStreetMap. Именно этого нам недостает для базового слоя геометрии — выгружаем все объекты с ключами building=* и addr:city='Санкт-Петербург'. Заодно прихватим ключи с именем, адресом и годом постройки (изредка он бывает заполнен). Получаем сто сорок три тысячи объектов, из которых про две тысячи есть информация о годе постройки.

Eсли накинуть все адреса из паспортов домов как точки и выделить полигоны с годами из «объектно-адресной системы» и OSM — можно оценить покрытие. Оцениваем: очень много серых пятен — продолжаю искать исходные данные.
Искать долго не приходится, есть прекрасный «Архитектурный сайт Санкт-Петербурга CityWalls.ru». Деликатно собираем данные с портала, получаем табличку с адресом, годами постройки, именем архитектора, архитектурным стилем, ссылками на страницу сооружения и его фотографию. Таких записей 27 тысяч, но часть из них — утраченные здания.
Быстро превращаем адреса в точки, накидываем на карту вместе с предыдущими слоями - кажется покрытые очень приличное, ура!

Теперь нужно все эти данные собрать вместе, причесать и преобразовать в симпатичный вид.
ГЕОПРОЦЕССИНГ
Для решения геоинформационных задач использовал QGIS и ArcGIS Pro, если нужно было что-то автоматизировать на Python — PyCharm.

В первую очередь, готовлю слой зданий, который потом буду максимально наполнять атрибутами. Основа слоя — «Объектно-адресная система Санкт-Петербурга» с портала открытых данных Санкт-Петербура, геометрия детальная, видимо, из кадастровых паспортов, смотрится красиво, бонусом забираем все мосты. Максимально избавляемся от ненужных нам полигонов набережных, подъездных путей, площадок складирования и т.п.

Из выгрузки OpenSteetMap забираем все полигоны, которые не пересекаются с полигонами из первого слоя. Получаем вот такой результат на сто сорок две тысячи объектов, полезные атрибуты из исходных слоёв уже включены.
Базовый слой зданий «Объектно-адресная система Санкт-Петербурга»+ OpenStreetMap
«Технико-экономические паспорта многоквартирных домов» это таблица, в которой один из столбцов — адрес. Для того, чтобы использовать эти данные, таблицу нужно геокодировать — каждой записи сопоставить точку с координатами. Пишем простой скрипт на Python, который с помощью одного из сервисов геокодирования добавляет столбцы широты и долготы в таблицу. По пути теряем небольшой процент записей — некоторые адреса не удается обработать.

На сайте СityWalls.ru простая структура, данные несложно собрать автоматически. Пишу простенький парсер, который собирает ссылку на страницу дома, его id на портале, текстовую строку: года постройки, архитектурный стиль, архитектора, название, адрес и ссылку на фотографию. Координаты с сайта не подходят — пользователи часто отмечают точки рядом с домом, а не сам дом, поэтому сам геокодирую слой, используя уже готовый скрипт. В результате — географические точки с аттрибутами на двадцать семь тысяч зданий.

По простому принципу — если точка находится на полигоне — присоединяем информацию из «Паспортов» и CityWall к зданиям. Теперь про каждый полигон у нас есть табличка с кучей информации из разных источников:
  • «Объектно-адресная система Санкт-Петербурга»
  • OpenStreetMap
  • «Технико-экономические паспорта многоквартирных домов»
  • СityWalls

Похоже на помойку. В итоге хочется иметь на каждое здание аккуратный набор атрибутов:
  • название
  • год постройки
  • архитектор
  • стиль
  • адрес
  • ссылку на страницу CityWalls
  • ссылку на фотографию
  • id

Эмпирически определяем приоритет источников для атрибутов, например, адреса лучше всего указаны в слое «Объектно-адресная система», хорошо — в «Паспортах» и примерно одинаково по качеству — в CityWalls и OpenStreetMap

Отдельный прикол с годом, для анализа нужно число, а во всех источниках — это строка, причем формат очень разнообразный: это может быть понятный "1703" или "1703г", список годов "1703,2020", период строительства "1822-1917", эпоха "до 1822", или прекрасное "1 9471 94 8", а также их комбинации и исключения.

Немного покрутив данные и пару раз сделав плохой выбор, нахожу правило, которое дает приличный результат: берем первое четырехзначное число из строки, если это не период, иначе — второе из первого периода в строке. Немного мучений с магией регулярных выражений, и в одну строку кода превращаем все текстовые поля дат в числа.

Зеленый - полигоны с годами, красный - без года
Если смотреть на процент заполнения (из ста сорока двух тысяч полигонов, года есть только для пятидесяти пяти), кажется, что покрытие вышло слабое, но если оценить на пространственное распределение, и качество объектов (например, дома против трансформаторных будок), получается прилично. Визуально кажется, что задачу слой выполняет: видны пространственные паттерны, дырок визуально мало, или они распределены равномерно. Слой интересно изучать, но перфекционист хочет полного покрытия, перфекциониста пока придушим.

Стоит оценить качество полученных данных. Из базовых методов, всегда доступно — можно посмотреть на график:
Сразу бросаются в глаза два пика — 1917 и 2008 год. Провалы после революции, Великой Отечественной войны и распада Советского союза — логичны и читаемы. Как быть с двумя выбросами? Гипотеза такая — многие дома дореволюционной постройки помечены как 1917, всякие варианты "до/предположительно" я отмечал.

2008 год — это, и вправду, период активного строительства в Петербурге. Цифры за 2008 на сайте Комитета по строительству и архитектуре меньше, но это ни о чем не говорит. К сожалению, я не помечал из какого источника взят год в итоговой таблице, расследование отложу на потом.

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

Ура! Данные обработали, качество оценили, можно визуализировать.

Кстати, набор свободно доступен по лицензии CC BY-SA в разделе "Данные".
ПАЛИТРА ЦВЕТОВ
Опыт коллег подсказывает, что выигрышно смотрится представление возраста домов в непрерывной палитре от горячих цветов к холодным, на темном фоне. Попробуем:
возьмем стандартную темную базовую карту от ESRI и цветовую палитру Spectral, предустановленную в QGIS:
Смотрится эффектно, но хочется, чтобы было круто и как-то связано с Петербургом.

Задача - подобрать цвета для базовой карты и домов. Один из моих любимых фотографов Петербурга — Андрей Михайлов, цвета на его фотографиях созвучны с моим "чувством города". Из инстаграмма фотографа набираю картинки, чтобы выудить из них ключевые цвета.