#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])
Это сработало.