Как рассчитать расстояние с помощью геопанд

#geopandas

#геопанды

Вопрос:

Я хотел рассчитать расстояние от Манилы до городов на Филиппинах, используя функцию geopandas GeoSeries.distance (self, other).

Шаги:

 # So I start with the dataset, which should produce a geopandas dataframe consisting basically of cities and a polygon of its boundaries in latlong.

url = 'https://raw.githubusercontent.com/macoymejia/geojsonph/master/MuniCities/MuniCities.minimal.json'
df1 = gpd.read_file(url)

# then I define a centroid column
df1['Centroid'] = df1.geometry.centroid

# then I define Manila location as a shapely point geometry, which produces a DataFrame with point geometry and address as columns
manila_loc = gpd.tools.geocode('Manila')

# then I try to calculate the distance
df1.Centroid.distance(manila_loc.geometry)

 

Но я получаю эту ошибку:

 AttributeError                            Traceback (most recent call last)
<ipython-input-30-76585915942f> in <module>
----> 1 df1.Centroid.distance(manila_loc.geometry)

~/opt/anaconda3/envs/Coursera/lib/python3.8/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5137             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   5138                 return self[name]
-> 5139             return object.__getattribute__(self, name)
   5140 
   5141     def __setattr__(self, name: str, value) -> None:

AttributeError: 'Series' object has no attribute 'distance'
 

Я новичок в GeoPandas, но из документации я подумал, что метод distance может работать с геосериями и что df1.Centroid и manila.geometry являются допустимыми объектами геометрической формы. Так что я не знаю, чего мне не хватает. Помогите, пожалуйста.

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

1. Вам нужно создать Point объект, представляющий Manilla. И не забудьте убедиться, что вы работаете в соответствующем CRS

Ответ №1:

Попробуйте это

 # relevant code only
dists = []
for i, centr in df1.Centroid.iteritems():
    dist = centr.distance( manila.geometry[0] )
    dists.append(dist)
    print("Dist2Manila: ", dist)
 

Чтобы создать новый столбец для расстояний:

 df1["Dist2Manila"] = dists
 

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

1. Вы не получите разумных расстояний, если проекция не имеет типа equi-distance.

2. Я не думаю, что вам нужен цикл здесь

3. @PaulH Нужны шаги для комментариев / отладки. Сначала заставьте его работать, оптимизируйте код позже.

Ответ №2:

Вам нужно передать отдельный Point объект методу distance:

 from shapely.geometry import Point
from geopandas import GeoDataFrame

destination = Point(5, 5)

geoms = map(lambda x: Point(*x), [(0, 0), (3, 3), (4, 1), (8, 2), (1, 10)])
departures = GeoDataFrame({'city': list('ABCDE'), 'geometry': geoms})
print(departures.assign(dist_to_dest=departures.distance(destination)))
 

Что дает мне:

   city                  geometry  dist_to_dest
0    A   POINT (0.00000 0.00000)      7.071068
1    B   POINT (3.00000 3.00000)      2.828427
2    C   POINT (4.00000 1.00000)      4.123106
3    D   POINT (8.00000 2.00000)      4.242641
4    E  POINT (1.00000 10.00000)      6.403124
 

Ответ №3:

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

 df1.Centroid.distance(manila_loc.geometry)
 

Для:

 gpd.GeoSeries(df1.Centroid).distance(manila_loc.iloc[0,0])
 

Это сработало.