2GIS больше не нужен: работаем с картами в OSMnx Python

В этой статье мы расскажем о работе с бесплатной и открытой картой мира Open Street Map в Python. Для взаимодействия с ней воспользуемся библиотекой OSMnx, которая позволяет загружать, обрабатывать, визуализировать, анализировать уличные сети Open Street Map. Также читайте в нашей статье, как рассчитать маршрут от нью-йоркских отелей до Эмпайр-стейт-билдинг.

Установка OSMnx и датасет c отелями

Прежде всего установим библиотеку OSMnx. Это можно сделать через загрузку и настройку всех необходимых зависимостей или с помощью Docker-образа. Развертывание будет выглядеть так:

  • Windows
    docker run --rm -it -p 8888:8888 -v "%cd%":/home/jovyan/work gboeing/osmnx:latest
    
  • Mac/Linux:
    docker run --rm -it -p 8888:8888 -v "$PWD":/home/jovyan/work gboeing/osmnx:latest
    

После загрузки, в адресной строке веб-браузера набирается http://localhost:8888.

В качестве примера будем использовать датасет, содержащий информацию о местах Нью-Йорка, где можно пожить некоторое время (для простоты мы будем называть их отелями). Скачать его можно на сайте Kaggle — онлайн-площадке соревнований по Machine Learning. Перед началом импортируем нужные библиотеки и прочитаем датасет:

import osmnx as ox
import networkx as nx
import pandas as pd

data = pd.read_csv('AB_NYC_2019.csv')

Вот так выглядят некоторые из атрибутов датасета:

Отображение данных pandas Python
Некоторые из атрибутов датасета

Ключевыми атрибутами для нас являются географические координаты — долгота longitude и ширина latitude. Ход выполнения работы можно также посмотреть в видеобзоре.

Определяем подходящий отель

Попробуем найти отели, удовлетворяющие нашим условиям. Например, они должны:

  • находиться в Манхэттене;
  • быть недорогими;
  • предоставлять комнату на 1 или 2 ночи;
  • быть популярными (иметь количество отзывов больше среднего);
  • иметь приватный тип комнаты;
  • быть доступными для бронирования хотя бы больше 300 дней.

Подобные условия можно выполнить, воспользовавшись булевой индексацией Pandas, которую мы обсуждали тут. Для этого напишем следующий код:

target = data[
    (data.neighbourhood_group == 'Manhattan') &
    (data.price < data.price.quantile(.2)) &
    (data.minimum_nights < 3) &
    (data.number_of_reviews > data.number_of_reviews.mean()) &
    (data.room_type == 'Private room') &
    (data.availability_365 > 300)
]

Стоит отметить, второе условие указывает на то, что цена проживания должна быть меньше 0.2 квантиля, что соответствует $60.

Таким образом, после фильтрации мы получили 18 отелей Манхэттена.

Строим на карте отели и Эмпайр-стейт-билдинг с OSMnx

Построим полученные отели на карте Манхэттена. В первую очередь, нужно получить граф c помощью функции graph_from_place Python-библиотеки OSMnx. В качестве аргументов она получает запрос к Open Street Map в виде местоположения. Также можно указать вид передвижения (пешком, на машине, на велосипеде и т.д.). Мы пойдем пешком:

G = ox.graph_from_place('Manhattan, New York, USA', network_type='walk')

Далее, метод plot_graph построит карту (граф). Он принимает аргументом вычисленный граф. Кроме того, выделим точками на карте полученные отели, а также Эмпайр-стейт-билдинг. Так как метод plot_graph использует библиотеку matplotlib, то мы имеем право добавить свои данные, например, с помощью метода scatter, о котором шла речь тут.

lat_target = target.latitude # массив координат отелей
lng_target = target.longitude

lat_ESB = 40.748817 # координаты Эмпайр-стейт-билдинг
lng_ESB = -73.985428

fig, ax = ox.plot_graph(G, figsize=(5,5), close=False, show=False)
ax.scatter(lng_target, lat_target, c='red', s=100) # точки отелей
ax.scatter(lng_ESB, lat_ESB, c='green', s=500) # точка Эмпайр-стейт-билдинг

Стоит отметить, для того чтобы иметь возможность редактировать карту, аргументы show и close должны быть равны False. В результате получили:

Отображение карты Манхэттена c точками OSMnx Python
Карта Манхэттена с обозначенными отелями (красные точки) и Эмпайр-стейт-билдинг (зеленая точка)

Нахождение кратчайшего пути до Эмпайр-стейт-билдинг в OSMnx

Определим кратчайший путь от отеля до Эмпайр-стейт-билдинг. В первую очередь, нужно найти ближайшие ребра около точек: для отелей используется функция get_nearest_edges. Если точка всего одна, то нужен метод get_nearest_edge:

nearest_edges = ox.get_nearest_edges(G, lng_target, lat_target)
nearest_edge_ESB = ox.get_nearest_edge(G, (lat_ESB, lng_ESB))

Стоит обратить внимание: get_nearest_edges принимает векторы долготы и широты, соответственно, в то время как get_nearest_edge — одну точку (кортеж).

Построим маршрут от первого отеля до Эмпайр-стейт-билдинг. Чтобы найти кратчайший путь, воспользуемся Python-библиотекой networkx [1], которая позволяет работать с графами. В этой библиотеке есть функция shortest_path, определяющая кратчайший путь. Для построения маршрута используется функция plot_graph_route библиотеки OSMnx:

route = nx.shortest_path(G, nearest_edge_ESB[0], nearest_edges[0][0])
fig, ax = ox.plot_graph_route(G, route, figsize=(5,5))

Результатом является карта:

Отображение карты Манхэттена с кратчайшим маршрутом OSMnx Python
Кратчайший маршрут от первого отеля до Эмпайр-стейт-билдинг

Считаем затраченное время в OSMnx

Посчитаем сколько понадобится времени, чтобы добраться от первого отеля до Эмпайр-стейт-билдинг. Для этого нам нужно определить скорости (км/ч) и затраченное время маршрута (секунды):

G = ox.add_edge_speeds(G)
G = ox.add_edge_travel_times(G)

Чтобы получить время необходимо просуммировать все отрезки времени:

route_times = sum(ox.utils_graph.get_route_edge_attributes(G, route, 'travel_time'))
print('Затраченное время = %.0f секунд или %.0f минут' % (route_times, route_times/60))

В результате мы получили:

Затраченное время = 1189 секунд или 20 минут

 

Примеры можно посмотреть в github репозитории. В следующей статье поговорим о том, как решается задача регрессии на примере этого же датасета с отелями. Еще больше практических примеров работы с географическими картами в Python, вы узнаете на наших курсах в лицензированном учебном центра обучения и повышения квалификации ИТ-специалистов в Москве.

Источники
  1. https://networkx.github.io/
  2. Youtube-канал Школа Больших данных/ Учебный центр «Коммерсант»

Добавить комментарий

Поиск по сайту