OpenStreetMap (OSM) - Некоммерческий веб-картографический проект по созданию силами сообщества участников - пользователей Интернета подробной свободной и бесплатной географической карты мира.
- Сайт: OpenStreetMap
Overpass API - это API только для чтения, предоставляющее доступ к базе данных OpenStreetMap. Оно позволяет пользователям выполнять запросы и извлекать конкретные географические данные из OSM на основе различных критериев, таких как местоположение, теги и свойства. Overpass API - мощный инструмент для получения данных OSM, отвечающих определенным требованиям.
- Сайт: Overpass API
Overpass Turbo - это веб-инструмент, предоставляющий пользовательский интерфейс для взаимодействия с Overpass API. Он позволяет пользователям создавать и выполнять запросы к данным OSM, визуализировать результаты на интерактивной карте и экспортировать данные в различных форматах. Overpass Turbo vereinfacht den Prozess der Exploration und Extraktion von OSM-Daten für unterschiedliche Zwecke.
- Сайт: Overpass Turbo
OpenStreetMap, Overpass API и Overpass Turbo хранят геоданные с использованием специализированной модели данных, называемой моделью данных OpenStreetMap. Географические данные в OSM представлены в виде узлов (nodes), линий (ways) и отношений (relations). Узлы представляют отдельные точки с координатами, линии представляют линейные объекты, такие как дороги и реки, а отношения представляют собой коллекции узлов, линий и других отношений для представления сложных или многофункциональных объектов.
Геоданные в OpenStreetMap хранятся в распределенной форме на нескольких серверах и организованы в иерархическую структуру, называемую сеткой тайлов. Каждый тайл содержит определенную область карты и связан с уникальным идентификатором. Эта структура позволяет эффективно хранить, извлекать и отображать геоданные для различных картографических приложений.
OSMnx - это библиотека на языке Python, позволяющая получать, анализировать и визуализировать данные OpenStreetMap. Она предоставляет простой в использовании интерфейс для загрузки данных OSM для конкретных регионов, создания графов сети на основе дорожных данных и выполнения различных задач анализа сети. OSMnx особенно полезен для градостроителей, исследователей и разработчиков, работающих с пространственными и транспортными данными.
- Документация: OSMnx
NetworkX (NX) - это библиотека на языке Python для создания, манипулирования и изучения структуры, динамики и функций комплексных сетей. Она предоставляет широкий набор инструментов и алгоритмов для анализа сетей, включая меры центральности, анализ связности и поиск пути. NX может использоваться совместно с OSMnx для анализа и обработки графов сети, извлеченных из OpenStreetMap.
Убедитесь, что у вас установлены следующие пакеты osmnx
,networkx
, matplotlib
в вашей среде Python (pip install osmnx networkx matplotlib
).
import osmnx as ox
import networkx as nx
import matplotlib.pyplot as plt
# Указываем местоположение для получения графа дорог
place_name = "Nur-Sultan, Kazakhstan"
# Получаем граф дорог для указанного местоположения
graph = ox.graph_from_place(place_name, network_type='drive')
Параметр network_type
: определяет тип дорожной сети для извлечения. Некоторые доступные значения включают all
(все типы дорог), walk
(только пешеходные дорожки), bike
(только велосипедные дорожки), drive
(только дороги для автомобилей), drive_service
(только служебные проезды: внутриквартальные, въездные, парковочные )
Примечание:
walk
,bike
отображают все типы дорог почему-то все равно (так что нужно провести дополнительную фильтрацию, если нужно вытащить только пешеходный дорожный граф)
Фильтруем, чтобы получить только пешеходный дорожный граф:
# Создайте копию графа (по желанию)
filtered_graph = graph.copy()
# Итерируйтесь по каждому ребру графа
for u, v, k, data in graph.edges(keys=True, data=True):
# Проверьте тип дороги на пешеходные тропы
if "footway" not in data["highway"] and "path" not in data["highway"]:
# Если тип дороги не является пешеходной тропой, удаляем ребро из графа
filtered_graph.remove_edge(u, v, k)
# Отображаем ребра графа дорог (если хотите отобразить отфильтрованный, то graph замените на filtered_graph)
fig, ax = ox.plot_graph(graph, edge_color='white', edge_linewidth=0.5, node_size=0, show=False)
# Показываем граф
plt.show()
-
Пример отображенного дорожного графа с
network_type="drive"
(только автомиобильные дороги): -
Пример отображенного дорожного графа с
network_type="all"
(все типы дорог): -
Пример отображенного пешеходного дорожного графа после фильтрации (только пешеходные):
Убедитесь, что у вас установлены следующие пакеты osmnx
,matplotlib
в вашей среде Python (pip install osmnx matplotlib
).
Примечание: чтобы получить маршрут от точки A к точке B !именно по дорожному графу, необходимо сначала получить ближайший узел дорожного графа к заданной вами координате
В примере ниже получаем маршрут используя
ox.distance.shortest_path
- кратчайший путь по алгоритму Дейкстры, но также имейте ввиду, что можно использоватьosmnx.distance.k_shortest_paths
- получить k заданное количество кратчайших путей по алгоритму Йена подробнее в документации
import osmnx as ox
import matplotlib.pyplot as plt
# Указываем местоположение для получения графа дорог
place_name = "Nur-Sultan, Kazakhstan"
# Создайте граф дорожной сети из OpenStreetMap данных
graph = ox.graph_from_place(place_name, network_type='drive')
# Задайте координаты двух точек (широта и долгота) и сразу получаем ближайший узел дорожного графа
point1 = ox.distance.nearest_nodes(graph, 71.4375894, 51.1247571) # координаты в ввиде (x, y) долгота, широта
point2 = ox.distance.nearest_nodes(graph, 71.36435335414731, 51.19407083146049) # координаты в ввиде (x, y) долгота, широта
# Добавьте геометрию (точки) на граф дорожной сети
ox.distance.add_edge_lengths(graph)
# Рассчитайте кратчайший путь и расстояние между точками
route = ox.distance.shortest_path(graph, point1, point2, weight='length')
# Получите длины ребер в маршруте и суммируйте их
distance = sum(ox.utils_graph.get_route_edge_attributes(graph, route, 'length'))
print(f'Расстояние между точкой 1 и точкой 2: {distance} метров')
Для отображения маршрута на графике с помощью matplotlib:
- убедитесь, что у вас установлены следующие пакеты
folium
в вашей среде Python (pip install folium
) - добавьте следующий код в ваш скрипт
# Получите геометрию маршрута
route_geom = ox.plot_route_folium(graph, route=route, route_color='blue', route_width=4, edge_width=2)
# Построить граф дорожной сети и отобразить на нем маршрут
fig, ax = ox.plot_graph_route(graph, route, route_linewidth=4, node_size=0, bgcolor='w')
# Показать график
plt.show()
Пример отображенного маршрута между 2мя точками с network_type='drive'
:
Distance Matrix API позволяет получить информацию о расстоянии (и времени - пока не входит) в пути между точками на карте.
filteredMarkersLngLat
- содержит координаты точек на карте в виде [lng, lat]
, т.е [долгота, широта]
{
"filteredMarkersLngLat":[
[71.416287,51.110922],
[71.411893,51.118386],
[71.418481,51.11747],
[71.423956,51.11671]
],
"counterFilteredMarkersLngLat":4
}
Расстояния как массив массивов, представляющих матрицу, в порядке соответсвующим входным данным. distances[i][j]
дает расстояние пути от i-го
источника до j-го
пункта назначения. Все значения указаны в метрах. Расстояние между одной и той же координатой всегда равно 0
{
"distances": [
[0, 1149.1499999999999, 752.18, 1112.069],
[1158.594, 0, 520.776, 917.913],
[774.1560000000001, 471.019, 0, 427.081],
[1099.2569999999998, 862.416, 391.39700000000005, 0]
]
}
import osmnx as ox
import json
# Загрузка данных из файла JSON
with open('./json/filtered_points_small.json', 'r') as file:
data = json.load(file)
points = data["filteredMarkersLngLat"]
# Преобразование координат точек в числа
for i in range(len(points)):
points[i] = [float(coord) for coord in points[i]]
# Создание графа дорожной сети из OpenStreetMap данных
graph = ox.graph_from_place('Nur-Sultan, Kazakhstan', network_type='drive')
ox.distance.add_edge_lengths(graph)
# Функция для рассчета расстояния между двумя точками
def calculate_distance(graph, point1, point2):
route = ox.distance.shortest_path(graph, point1, point2, weight='length')
# distance = sum(ox.utils_graph.get_route_edge_attributes(graph, route, 'length')) osm_distance_matrix.py:22: UserWarning: The `get_route_edge_attributes` function has been deprecated and will be removed in a future release. Use the `route_to_gdf` function instead.
distance = sum(ox.utils_graph.get_route_edge_attributes(graph, route, 'length'))
return distance
# Рассчет расстояний от каждой точки до всех остальных точек
distances = []
for i, point in enumerate(points):
point_coords = point
point_node = ox.distance.nearest_nodes(graph, point_coords[0], point_coords[1])
distances.append([])
for j, other_point in enumerate(points):
other_point_coords = other_point
other_point_node = ox.distance.nearest_nodes(graph, other_point_coords[0], other_point_coords[1])
distance = calculate_distance(graph, point_node, other_point_node)
distances[i].append(distance)
# Сохранение результатов в виде матрицы расстояний в новый JSON-файл
output_data = {'distances': distances}
with open('./json/output_distance_matrix_small.json', 'w') as output_file:
json.dump(output_data, output_file)
print("Матрица расстояний сохранена в файле 'output_distance_matrix.json' в папке json.")
Для получения объектов, таких как парки, здания, другие достопримечательности и учреждения.
Для отображения объектов на графике с помощью matplotlib:
- убедитесь, что у вас установлены следующие пакеты
geopandas
,pandas
в вашей среде Python (pip install geopandas pandas
)
import osmnx as ox
import geopandas as gpd
import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt
# Указываем местоположение для получения графа дорог
place_name = "Nur-Sultan, Kazakhstan"
# Define the tags for filtering objects
# tags = {'tourism': True, 'amenity': True, 'leisure': True}
tags = {'leisure': True}
# Retrieve all the points of interest (POIs) in the specified place
gdf = ox.geometries.geometries_from_address(place_name, tags, dist=10000) # dist in meters
gdf.plot(ax=plt.gca(), color='red', alpha=0.6, markersize=10)
# Отображаем карту
plt.show()
Пример отображенных объектов с leisure=true
(развлекательных и спортивных объектов, в том числе парки)
- https://osmnx.readthedocs.io/ - документация OSMnx
- https://wiki.openstreetmap.org/wiki/Map_features - описание всех тегов OSM
- https://habr.com/ru/articles/688556/ - чувак на Java работатет с OSM