如何解析 Nominatim 反向地理编码返回的地址组件?

How parse address components returned by Nominatim reverse geocoding?

所以,我正在开发一个用于地理标记图像的地图应用程序,我想在我的地图上包含兴趣点的地址信息。我已经成功地使用 Geopandas、GeoPy 和 Nominatim 以及来自 PostGIS table 的点数据完成了大部分任务(例如 POINT Z (8.726176366993529 50.10868874301912 96.90000000000001)。

虽然脚本完成了我想要的大部分工作,但结果 returns 有很多无关信息,我想在更新数据库之前将其解析为一两个数据。我能够使用 gecoding and reverse geocoding 上的两篇文章破解我的脚本。我的问题归结为不确定脚本如何接收响应对象以及我如何在将属性添加到我的 Dataframe 之前或之后访问这些属性。

我没有import语句的代码如下:

conn = psycopg2.connect(
    host="localhost",
    database="Nizz0k",
    user="Nizz0k",
    password="")
sql = "select * from public.\"Peng\""
engine = create_engine('postgresql://Nizz0k@localhost:5432/public.\"Peng\"')
df = gpd.read_postgis(sql, conn, geom_col="geom")
df['lon'] = df.geometry.apply(lambda p: p.x)
df['lat'] = df.geometry.apply(lambda p: p.y)
df['geocode'] = df['lat'].map(str) + ', ' + df['lon'].map(str)
locator = Nominatim(user_agent="pengMappingAgent", timeout=10)
rgeocode = RateLimiter(locator.reverse, min_delay_seconds=0.001)
tqdm.pandas()
df['address'] = df['geocode'].progress_apply(rgeocode)

所以,我的 Python 知识非常有限,但我尝试访问新创建的 df['address'] 列中的属性似乎没有任何效果。调用 df.head() 显示正确创建的列和地址信息,但现在我想简化列中的信息并将其部分提取到新列中。理想情况下,我想提取街道和门牌号信息以及社区信息,并删除城市、县、州和国家信息,因为它们是多余的。

根据我所做的研究,我应该能够从响应对象中提取此信息,但我不确定从何处或如何访问它。似乎此信息在我的专栏中被转换为字符串(我认为),如果没有,我不确定如何设置循环或 lambda 函数来获取这些内容。最坏的情况是,我假设只需一些字符串操作就可以实现我的目标,但似乎应该有更简单的方法。

  • 显然我无法连接到您的数据库,因此模拟了一个 GeoDataFrame,这是一系列点
  • 然后简化了调用 Nominatim
  • 的代码
  • raw returns a dict 这可以按照下面的代码提取
import geopandas as gpd
import shapely.geometry
from geopy.geocoders import Nominatim
import pandas as pd

gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))

# a geodata frame with a few points...
df = gpd.GeoDataFrame(
    geometry=gdf.loc[gdf["iso_a3"].eq("BEL"), "geometry"]
    .apply(lambda p: p.exterior.coords)
    .explode()
    .apply(shapely.geometry.Point),
    crs="EPSG:4326",
).reset_index(drop=True)

locator = Nominatim(user_agent="pengMappingAgent", timeout=10)

df = df.join(df["geometry"].apply(lambda p: locator.reverse(f"{p.y}, {p.x}").raw["address"]).apply(pd.Series))

print(df.head(3).to_markdown(index=False))
df

输出

geometry road suburb city county state postcode country country_code house_number village hamlet town region locality municipality isolated_dwelling neighbourhood tourism
POINT (6.15665815595878 50.80372101501058) A 4 Verlautenheide Aachen Städteregion Aachen Nordrhein-Westfalen 52080 Deutschland de nan nan nan nan nan nan nan nan nan nan
POINT (6.043073357781111 50.12805166279423) Beieknapp nan nan Canton Clervaux nan 9962 Lëtzebuerg lu 14 Holler nan nan nan nan nan nan nan nan
POINT (5.782417433300907 50.09032786722122) nan nan nan Bastogne Luxembourg 6600 België / Belgique / Belgien be nan Noville Neufmoulin Bastogne Wallonie nan nan nan nan nan