- PVSM.RU - https://www.pvsm.ru -

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

Всем привет!



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

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

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

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

address

floor_count_max

built_year

is_alarm

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

2

1954

Нет

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

5

1977

Нет

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

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

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

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

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

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

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

Полигоны

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

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

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

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

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

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

Результат

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

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

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

Что дальше?

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

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

Реализация

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

Спасибо

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

Автор: Федор Родионов

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/nizhnij-novgorod/377055

Ссылки в тексте:

[1] GeoPandas: https://geopandas.org/en/stable/

[2] Kepler.gl: https://kepler.gl/

[3] Яндекс.Геокодер: https://yandex.com/dev/maps/geocoder/

[4] условия использования API Яндекс.Карт: https://yandex.ru/dev/maps/jsapi/doc/2.1/terms/index.html?from=geocoder#index__conditions

[5] статье про геокодирование: https://habr.com/ru/post/499990/

[6] раз: https://habr.com/ru/post/418799/

[7] два: https://habr.com/ru/post/422759/

[8] пост: https://habr.com/ru/post/463251/

[9] http://download.geofabrik.de/: http://download.geofabrik.de/

[10] принадлежность точки к полигону: https://en.wikipedia.org/wiki/Point_in_polygon#:~:text=One%20simple%20way%20of%20finding,an%20even%20number%20of%20times.

[11] статью: https://www.matecdev.com/posts/point-in-polygon.html

[12] репозитории: https://github.com/RodionovF/Nizhny_Novgorod_3d_map/blob/main/data/kepler_map.html

[13] посте: https://habr.com/ru/post/504216/

[14] Прикрепляю ссылку на GitHub: https://github.com/RodionovF/Nizhny_Novgorod_3d_map

[15] Источник: https://habr.com/ru/post/677314/?utm_source=habrahabr&utm_medium=rss&utm_campaign=677314