Python|批量获取Mapbox等时圈shapefile格式数据
直接获取Mapbox出行圈数据
Mapbox地图网站有个Isochone API接口Isochrone API|Playground|Mapbox,可以快速获得等时圈数据。
获取access token
-
打开Mapbox网站Maps, geocoding, and navigation APIs & SDKs | Mapbox,右上角登录或者注册。
-
登录后在网页最下面,可以看到Access tokens一栏,里面有一个默认的token(也可以新建一个),把这个token复制。
设置等时圈参数
-
打开mapbox的 Isochone API接口Isochrone API | Playground | Mapbox,可以看到网页界面由左侧参数,右侧地图,底部请求网址和返回json数据组成。
-
网站的使用比较简单,设置好参数之后即可得到等时圈数据。
参数名称 | 描述 |
---|---|
access token | 里填入第一步复制的token(默认已自动填好); |
longitude/latitude | 填入等时圈的起点经纬度,使用wgs84坐标系; |
routing profile | 选择walking步行、cycling骑行和driving驾车三种出行方式的其中一种,获得对应出行方式的等时圈; |
contour minutes | 有10 min、20 min、30 min和15 min increments四个选项,对应10分钟等时圈、20分钟等时圈、30分钟等时圈和15分钟增量等时圈(即15、30、45、60分钟等时圈,最大为60分钟); |
style | 可以选择返回polygons面数据或lines线数据; |
contour | colors可以选择等时圈颜色; |
denoise | 可以去噪,一般设置为1即可; |
generalize | 可以改变泛化容差,即改变边的曲折程度,一般设置为0即可。 |
下载等时圈数据
设置好参数后,网站即返回等时圈数据,在网页底部的response里,但该数据是GeoJSON格式,我们可以复制response里的内容,将其复制到txt文档中,并将文件后缀改为.json,然后直接将该json文件拖入QGIS中打开,再另存为shp文件。
也可以通过python的pyshp库或geopandas库去获取shp文件。下面介绍通过pyshp库批量获取mapbox等时圈数据的方法。
python批量获取等时圈数据
Mapbox使用Get方式请求,因此可以发现请求url如下:
通过分析可以看出,网址里walking代表出行方式,可以更换为driving驾车或cycling骑行;114.363574与30.471573为经纬度坐标;contours_minutes可以设置时间范围,最大为60分钟,可最多携带4个时间间隔,用逗号隔开;access_token=后需要填入你的token,其他参数按照默认的即可。
而对于返回的Response数据,等时圈的属性信息在features下的properties里,等时圈的几何信息在features下的geometry里。
搞清楚请求url和返回json数据的结构之后,就可以编写代码了。
导入需要使用的库
import time
import requests
import pandas as pd
import shapefile
from osgeo import osr
编写获取数据的函数
使用的参数包括起点名称name,起点经度lon,起点维度lat,出行方式transit。对于等时圈的范围,此处使用5、10、15、20分钟的距离,可根据需要自行调整。
def getdata(name, lon, lat, transit):
print('获取{}的等时圈'.format(name))
url = 'https://api.mapbox.com/isochrone/v1/mapbox/{}/{},{}?contours_minutes=5,10,15,20&polygons=true&denoise=1&generalize=0&access_token=你的token'.format(transit, lon, lat)
try:
r = requests.get(url, timeout=(3, 7)).json()
w = shapefile.Writer('./shp/isochrone_{}_{}.shp'.format(name, transit), encoding='gbk')
w.field('name', 'C')
w.field('transit', 'C')
w.field('contour', 'N')
w.field('metric', 'C')
w.field('color', 'C')
w.field('opacity', 'N', decimal=2)
for i in r['features']:
coords = i['geometry']['coordinates']
w.poly(coords)
w.record(
name=name,
transit=transit,
contour=i['properties']['contour'],
metric=i['properties']['metric'],
color=i['properties']['color'],
opacity=i['properties']['opacity']
)
w.close()
# 添加投影信息
proj = osr.SpatialReference()
proj.ImportFromEPSG(4326)
wkt = proj.ExportToWkt()
projfile = './shp/isochrone_{}_{}.prj'.format(name, transit)
f0 = open(projfile, 'w')
f0.write(wkt)
f0.close()
print('获取成功!')
except:
print('获取失败')
df = {}
df['name'] = name
df['lon'] = lon
df['lat'] = lat
df['transit'] = transit
dm = pd.DataFrame([df])
dm.to_csv('./queryagain.csv', mode='a', index=False, header=False, encoding='utf-8-sig')
把需要获取等时圈的起点信息保存在csv文件中
包括起点的名称name,经度lon,维度lat,出行方式transit,可以通过poi数据获取。读取csv文件后对等时圈起点进行批量获取
if __name__ == '__main__':
print('开始爬取数据')
dt = pd.read_csv('./subway.csv', engine='python', encoding="gbk")
for i in range(len(dt)):
getdata(dt['name'][i], dt['WGS84_Lng'][i], dt['WGS84_Lat'][i], dt['transit'][i])
time.sleep(0.5)
print('All Done!!!')
文件组织格式如下: