Python GeoPandas Tutorial
Python GeoPandas Tutorial
1. 读写数据
A. 查看支持的文件类型
import pandas as gpd
# Check supported format drivers
gpd.io.file.fiona.drvsupport.supported_drivers
# 等价于
import fiona
fiona.supported_drivers
B. 读取文件
gpd.read_file()
# 读取 url,geojson 文件
gpd.read_file("http://*/data.geojson", river="GeoJSON")
# 读取 zip 文件中的 shp 文件
gpd.read_file("zip:///data_shp.zip!data/location.shp")
主要参数:
driver:指定文件格式,默认为.shp文件crs:设置坐标系
C. 写入文件
GeoDataFrame.to_file() # driver 参数 指定文件格式
GeoDataFrame.to_wkb()
GeoDataFrame.to_wkt()
D. GeoDataFrame 初始化
主要参数:
-
geometry:应当为geopandas.GeoSeries;或者 list 类型,元素为shapely.geometry下类型 -
crs:地理坐标系
实例:
from shapely.geometry import Point
# 'geometry' 列指明 geometry 参数
data = {'col1': ['name1', 'name2'], 'geometry': [Point(1, 2), Point(2, 1)]}
gdf = geopandas.GeoDataFrame(data, crs="EPSG:4326")
2. 主要方法
geopandas.GeoSeries 主要方法:site
geopandas.GeoDataFrame 主要方法:site
2.1 空间分析方法
2.1.1 空间连接 Spatial join
属性连接(Attribute Joins):Pandas 库中 pandas.join() 方法
空间连接(Spatial join):GeoPandas 库中 geopandas.sjoin() 方法
- 通过参数
predicate指定几何关系,实现连接
如:left_df=cities 为城市,geomtery 属性为 Point 类型,right_df=countries 为国家,geomtery 属性为 Polygon 类型。通过下述函数,可以实现城市和国家的匹配
geopandas.sjoin(left_df=cities, right_df=countries, how="left", predicate='within')
最邻近空间连接:geopandas.sjoin_nearest()
主要参数:
-
left_df, right_df (geopandas.geodataframe.GeoDataFrame) -
how (str):'left', 'right', 'inner' -
max_distance (float) -
lsuffix, rsuffix (str) -
distance_col (str):保存连接的几何对象的距离
2.1.2 Overlay
element-wise 操作,参考:
3. Geocoding in Geopandas
3.1 地理编码工具
3.2 GeoPy 库
A. Nominatim
Nominatim: 基于 OSM 的地理编码:官网,在线查询
初始化:
geolocator = Nominatim(user_agent="my_application")
# 建议定义 user_agent 名称
地理编码:.geocode() 方法
loc = geolocator.geocode(query, *)
主要参数:
-
query (str or dict):- 对于
dict类型:其 key 为 street, city, county, state, country, postalcode
- 对于
-
exactly_one (bool):-
True 表示只返回一个最接近的结果
-
False,返回 list 类型,返回所有查询结果
-
-
addressdetails (bool):是否返回地址的详细结果 -
country_codes (str or list):通过 country code(s) 将查询范围现在指定的国家内- ISO 3166-1alpha2 code:site
-
viewbox (list or tuple):包含两个元素的 list 或 tuple,每个元素为geopy.point.Point或(latitude, longitude)或"%(latitude)s, %(longitude)s"- 将查询范围限制在指定的 box 内,只有设置参数
bounded=True才会生效
- 将查询范围限制在指定的 box 内,只有设置参数
-
bounded (bool):是否将查询范围限制在viewbox参数指定的 box 内
返回结果:None, 或 geopy.location.Location,或 list(当设置 exactly_one = False)。geopy.location.Location 类主要属性有:
-
.address -
.latitude,.longitude,.altitude -
.point:返回geopy.point.Point类型 -
.raw
逆地理编码:.inverse() 方法
loc = geolocator.geocode(query, *)
主要参数:
query:包含两个元素的 list 或 tuple,每个元素为geopy.point.Point或(latitude, longitude)或"%(latitude)s, %(longitude)s"
实例: 地理编码 .geocode() 方法
from geopy.geocoders import Nominatim
# 初始化一个 Nominatim 实例
geolocator = Nominatim(user_agent="my_application")
query = "National University of Singapore"
res = geolocator.geocode(query, exactly_one=True, country_codes="sg")
print(res.point)
print(res.address)
print(res.raw)
3.2.2 RateLimiter 类
OSM 的 Nominatim 限制 API 请求频率在 1 秒以上,参见 site
GeoPy 库中 geopy.extra.rate_limiter.RateLimiter() 用于控制 API 请求频率。
实例:
from geopy.geocoders import Nominatim
from geopy.extra.rate_limiter import RateLimiter
geolocator = Nominatim(user_agent="my_app")
# 使用 RateLimiter 类 wrap geolocator.geocode() 方法
geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1.)
# 传入 geolocator.geocode() 方法的参数
res = geocode(query='nus', country_codes="sg", exactly_one=True)
# 输出
print(res.address)
print(res.location)
实例: 对 pandas.DataFrame 中的地址信息实现地理编码
import pandas as pd
from geopy.geocoders import Nominatim
from geopy.extra.rate_limiter import RateLimiter
# 待解析地址
df = pd.DataFrame({'name': ['nus', 'ntu', 'smu']})
geolocator = Nominatim(user_agent="my_app")
geocode = RateLimiter(geolocator.geocode, min_delay_seconds=1.) # 请求间隔为 1 s
df['location'] = df['name'].apply(geocode,
country_codes='sg', exactly_one=True) # 传入到 geocode 中的参数
df['point'] = df['location'].apply(lambda loc: tuple(loc.point) if loc else None) # 从请求结果中提取 经纬度坐标
df['address'] = df['location'].apply(lambda loc: loc.address if loc else None) # 从请求结果中提取 地址
3.3 geopandas.tools.geocode() 方法
实际上,该方法通过 geopy 库实现
Geocoding in Geopandas:site
geopandas.tools.geocode:site
实例: 使用 geopandas.tools.geocode() 方法
import pandas as pd
import geopandas as gpd
df = pd.Series(['nus', 'ntu', 'smu'])
df = gpd.tools.geocode(df, provider='nominatim', user_agent='my_app')
该方法存在的缺点:无法设置 geopy 库中 .geocode() 方法的参数。因此,推荐使用 3.2 节中的实例方法。

浙公网安备 33010602011771号