Как один мужик карту города рисовал

Всем привет! 



Сегодня поговорим о визуализации геоданных с помощью GeoPandas и Kepler.gl. Хотел бы рассказать, как я за пару дней построил вот такую карту, где высота полигонов регулировалась этажностью здания, а цвет — годом постройки.

Нижний НовгородНижний Новгород

Постановка задачи

Когда я работал 2 года назад (август 2020) в одной нижегородской компании, ко мне пришёл мой начальник и сказал, что мне надо визуализировать аварийные и старые дома в нашей области. Мне прислали .excel файл, где был указан адрес дома, количество этажей, год постройки и признак аварийности.

address

floor_count_max

built_year

is_alarm

д. г Навашино ул Соболева д. 1

2

1954

Нет

обл. Нижегородская, р-н. Ардатовский, рп. Ардатов, ул. 1 Мая, д. 32

5

1977

Нет

Геопроцесинг

Окей, подумал я. Стажировка в Яндекс.Картах не прошла даром, я знал о существовании такого сервиса, как Яндекс.Геокодер. Координаты я получу, останется нарисовать это где-нибудь. (О нем знали все в Картах, это было наше самое узкое место на тот момент. Инструмент очень важный и полезный для большинства сервисов, поэтому на команды был выделен строгий трафик).

Не тут-то было. Геокодер имеет жесткие бесплатные условия использования API Яндекс.Карт. Ранее число бесплатных запросов было порядка 20к, но сейчас уже давно 1к. Я стал искать ещё варианты.

Как посоветовали в статье про геокодирование, я использовал OSM геокодер. И взял на заметку комментарий, что проблемные случаи можно отправлять в Яндекс, поскольку для России, конечно же, Яндекс выдает более точные результаты. Но в текущей реализации я вообще не следил за качеством данных геокодирования и качеством сырых данных. Мне было интересно поскорее уже что-нибудь нарисовать.

И тут я наткнулся на классный инструмент — Kepler.gl. Прочитал пару постов на Хабре (раз, два) и понял что это то, что мне нужно. Я загрузил свою табличку, уже с координатами, и получил такой результат.

dfd8eee5753d564c8400e40179de6546.jpeg

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

Полигоны

Я понял, что мне нужно скачать 2d полигоны, но не знал где их взять, пока не наткнулся на замечательный пост. Достаточно было скачать с http://download.geofabrik.de/ свой округ и вырезать Нижегородскую область.

Далее началось самое интересное. В данных OSM уже была информация об этажах, но не везде. И не было информации о годе постройки и аварийности. Мне предстояло соединить файл с полигонами с табличкой с координатами и адресами. Я стал судорожно гуглить, как определить принадлежность точки к полигону. Реализовав простейший алгоритм, я стал запускать расчёты. План был следующий, для каждой точки координат я пытался найти полигон, в котором она лежит. Получился вложенный цикл. Количество полигонов было порядка 600,000, а количество адресов с координатами было 22,000. Можно было сделать сортировку по Долготе/Широте и немного сократить длину перебора, используя бинарный поиск. Но было всё равно ужасно долго. Подождав ± 10 часов, я получил результат. И так у меня это всё и работало до недавнего времени.

Пока я не наткнулся на интересную статью, в рамках подготовки к данному посту. Моя задача решалась одним джойном с использованием GeoPandas. Время выполнения стало 2 секунды. И ещё пару огромных плюсов заключается в том, что датафрейм можно сохранять сразу в .geojson, а не мучиться с конвертированием обычного .json. А исходный файл можно загружать сразу из .shp формата, который выдает геофабрика.

Советую всем использовать GeoPandas, это замечательный инструмент, я имел опыт работы с ним в университете, но совершенно забыл про него.

Результат матчинга на картинке. Точки уверенно попадают в полигоны.

e9a33d99cc362699b5a7ac0547678852.jpeg

Результат

В итоге у меня получилась отличная интерактивная карта, где у каждого дома есть своя табличка с информацией. Карту можно крутить, раскрашивать, менять фон. Kepler.gl можно кастомизировать. Карту в формате .html можно сохранить и отправить другим людям. Карта присутствует в репозитории.

167596232446f3d5253ceef44c044e40.jpeg

Видно, что много пустых полигонов. Бороться с этим можно с помощью улучшения качества сырых данных и геокодирования.

Что дальше?

Я уже составил гениальный план, что в карточки к домам можно добавлять информацию о доме, архитектуре, жильцах, различные фотографии. Но понял, что не изобрету ничего лучше существующих карт. А идею с реализацией раскраски полигонов уже выложили на Хабр 3 месяца назад в замечательном посте с красивыми постерами городов. Используются немного другие инструменты, но суть такая же.

Поэтому пришлось всё отложить в долгий ящик, пока я не нашёл время рассказать эту историю. А свою задачу тогда я выполнил.

Реализация

Прикрепляю ссылку на GitHub, где есть все исходные данные, итоговая карта и .ipynb файлы для личного повторения моего пути.

Спасибо

Приезжайте гулять в Нижний Новгород

© Habrahabr.ru