(欢迎转载,需要保留文末的个人微信公众号二维码)
pandas简介
看一个dataframe的实例
geopandas简介
DataFrame相当于GIS数据中的一张属性表,为了将pandas的特性用到空间数据,就有了geopandas。其目标是使得在python中操作地理数据更方便。
geopandas结合了pandas和shapely的功能,扩展了pandas在空间数据操作方面的能力,从而使得你可以轻松的用python实现空间数据分析。
看一个geodataframe的实例
与dataframe相对,直观的区别是多了一个geometry的字段。
安装
pip install geopandas
# or
conda install -c conda-forge geopandas
官网示例
先直接照搬一个官网上的例子
p1 = Polygon([(0, 0), (1, 0), (1, 1)])
p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)])
g = gpd.GeoSeries([p1, p2, p3])
g.plot()
可以非常方便的计算面积和缓冲区
print g.area
g.buffer(0.5).plot()
还有其他空间数据分析的功能,有兴趣可以去官网了解下。
示例2. 构建geodataframe对象
gepandas提供了多个读取矢量空间数据的接口,支持包括shapefile,geojson等。也支持直接从已有的dataframe对象生成geodataframe,示例如下:
df = pd.DataFrame(np.random.randn(50, 3),columns=['X', 'Y', 'Z'])
geom = [shapely.geometry.Point(xy) for xy in zip(df.X, df.Y)]
gdf = geopandas.GeoDataFrame(df, geometry=geom)
print type(gdf)
输出为
<class 'geopandas.geodataframe.GeoDataFrame'>
示例3. osm路网
下面这个例子,首先获取一个城市(如青岛)的空间范围,根据这个范围下载openstreetmap的道路数据存入geodataframe对象,然后绘制出来。
1. 获取空间范围
这里用之前提到的geocoder这个工具,网友也提到这些地理编码获取的坐标并不准确,我们暂且先不考虑精度的问题。
import geocoder
from shapely.geometry import Polygon
g = geocoder.arcgis(u"青岛")
min_lat = g.bbox.get('southwest')[0]
min_lon = g.bbox.get('southwest')[1]
max_lat = g.bbox.get('northeast')[0]
max_lon = g.bbox.get('northeast')[1]
boundary = Polygon([(min_lon, min_lat),(min_lon,max_lat),(max_lon,max_lat), (max_lon, min_lat)])
这样获取到的青岛市的空间范围(外接矩形)为
{'northeast': [36.209606, 120.482939], 'southwest': [35.987606, 120.260939]}
2. 下载osm数据
这里用到geopandas_osm这个工具,安装命令为
pip install
将空间范围的polygon对象作为参数即可,可以查看一下对象类型和投影参数:
import geopandas_osm.osm
df = geopandas_osm.osm.query_osm('way', boundary, recurse='down', tags='highway')
print type(df)
print df.crs
输出为
<class 'geopandas.geodataframe.GeoDataFrame'>
{'init': 'epsg:4326', 'no_defs': True}
直接获取到的osm数据比较乱,做进一步筛选:
way = df[df.type == 'LineString'][['highway', 'name', 'geometry']]
way.head()
可以计算道路的长度,这里只是示意。直接计算length并不对,应该先投影到平面坐标系。
df.ix[0].geometry.length
输出为
0.0014679943869086182
3. 绘制路网
可以直接用plot命令,绘制出来:
way.plot(column="name",colormap=cm.coolwarm_r)