Получение списка координат (широта, длина) из геосерии OSMNX

#python #geopandas #osmnx

#python #геопанды #osmnx

Вопрос:

Я хотел бы вычислить кратчайший путь между списком пунктов назначения и источником. Но сначала мне нужно найти узлы, ближайшие к моим пунктам назначения. Я получаю список пунктов назначения из функции OSMNX для набора точек интереса (geometries_from_place).

 import osmnx as ox
import geopandas as gpd
import networkx as nx
print(ox.__version__)
ox.config(use_cache=True, log_console=True)
Kinshasa = [ "Kisenso, Mont Amba, 31, Democratic Republic of the Congo",
"N'djili, Tshangu, Democratic Republic of the Congo",
"Kinshasa, Democratic Republic of the Congo"]
G_Kinshasa = ox.graph.graph_from_place(Kinshasa, simplify=True, network_type='drive')
tags2 = {'amenity' : ['hospital','university','social_facility'],
        'landuse' : ['retail', 'commercial'],
         'shop' : ['water','bakery']}
POIS = ox.geometries_from_place(Kinshasa, tags2, which_result=1)
Nearest_Nodes = ox.get_nearest_nodes(G_Kinshasa, POIS['geometry'][x],POIS[geometry][y])
 

Как я могу получить список значений lats и longs из объекта POIS[‘geometry’], который является геосерией, чтобы передать его в get_nearest_nodes в последней строке кода выше?
Вот пример вывода POI[‘geometry’]:

 Out[10]: 
0                             POINT (15.34802 -4.39344)
1                             POINT (15.34074 -4.41001)
2                             POINT (15.34012 -4.40466)
3                             POINT (15.34169 -4.40443)
4                             POINT (15.35278 -4.40812)
 

Ответ №1:

Вот минимально воспроизводимое решение (OSM не может геокодировать ваши запросы на размещение в их текущей форме, поэтому я выбрал тот, который работает только для демонстрационных целей). Обратите внимание, что я указываю balltree метод поиска ближайших узлов, поскольку вы работаете с непроецируемым графиком и непроецируемыми точками.

 import osmnx as ox
ox.config(use_cache=True, log_console=True)

place = 'Berkeley, CA, USA'
G = ox.graph_from_place(place, network_type='drive')

tags = {'amenity' : ['hospital','university','social_facility'],
        'landuse' : ['retail', 'commercial'],
        'shop' : ['water','bakery']}
gdf = ox.geometries_from_place(place, tags)

centroids = gdf.centroid
X = centroids.x
Y = centroids.y

nn = ox.get_nearest_nodes(G, X, Y, method='balltree')
 

Ответ №2:

Вы можете создать список кортежей с помощью простой лямбда-функции. Я не проверял производительность по отношению к другим возможным решениям, но для 5000 строк x 9 col. geodataframe это занимает около 120 мс на настольном ПК среднего класса.

 pointlist = list(POIS.geometry.apply(lambda x: ( x.x, x.y )))
 

Комментарии:

1. К сожалению, это не работает. Я получаю сообщение об ошибке, что объект ‘Polygon’ не имеет атрибута ‘x’

2. Я не узнал, что вы используете метод geometries_from_place osmnx, он вернет полигоны / мультиполигоны вместо точек. Вы должны использовать функцию, возвращающую точки, или определить функцию, вычисляющую x, y из полигонов, например, получение центроида.

3. Я получаю точки интереса из функции (geometries_from_place), поэтому у меня есть ТОЧКИ в качестве моего типа геометрии. Просто я не могу получить доступ к x и y в этих точках. Когда я вставляю type(POIS.geometry[1]) в Python, он возвращает shapely.geometry.point. Точка