【问题标题】:How to calculate distance using geopandas如何使用 geopandas 计算距离
【发布时间】:2020-12-10 15:05:41
【问题描述】:

我想使用 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 的新手,但我从文档中认为距离方法可以作用于 GeoSeries,并且 df1.Centroid 和 manila.geometry 是有效的形状几何对象。所以我不知道我错过了什么。请帮忙。

【问题讨论】:

  • 您需要创建一个代表马尼拉的Point 对象。并且不要忘记确保您在适当的 CRS 中工作

标签: geopandas


【解决方案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

【讨论】:

  • 如果投影不是等距离类型,您将无法获得合理的距离。
  • 我觉得你这里不需要循环
  • @PaulH 需要用于 cmets/调试目的的步骤。先搞定,再优化代码。
【解决方案2】:

您需要将一个单一的Point 对象提供给距离方法:

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])
    

    成功了。

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 1970-01-01
      相关资源
      最近更新 更多