Python|批量获取Mapbox等时圈shapefile格式数据

直接获取Mapbox出行圈数据

Mapbox地图网站有个Isochone API接口Isochrone API|Playground|Mapbox,可以快速获得等时圈数据。

image-20221127212425173

获取access token

  1. 打开Mapbox网站Maps, geocoding, and navigation APIs & SDKs | Mapbox,右上角登录或者注册。

  2. 登录后在网页最下面,可以看到Access tokens一栏,里面有一个默认的token(也可以新建一个),把这个token复制。

设置等时圈参数

  1. 打开mapbox的 Isochone API接口Isochrone API | Playground | Mapbox,可以看到网页界面由左侧参数,右侧地图,底部请求网址和返回json数据组成。

  2. 网站的使用比较简单,设置好参数之后即可得到等时圈数据。

image-20221127212425173_1
参数名称 描述
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如下:

https://api.mapbox.com/isochrone/v1/mapbox/walking/114.363574%2C30.471573?contours_minutes=15%2C30%2C45%2C60&polygons=true&denoise=1&access_token=你的token

通过分析可以看出,网址里walking代表出行方式,可以更换为driving驾车或cycling骑行;114.363574与30.471573为经纬度坐标;contours_minutes可以设置时间范围,最大为60分钟,可最多携带4个时间间隔,用逗号隔开;access_token=后需要填入你的token,其他参数按照默认的即可。

而对于返回的Response数据,等时圈的属性信息在features下的properties里,等时圈的几何信息在features下的geometry里。

image-20221127221310687

搞清楚请求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!!!')

文件组织格式如下:

image-20221127185749850

将批量获取的数据导入ArcGIS软件进行相关分析

image-20221127220642000
posted @ 2022-11-28 16:40  Weltㅤ  阅读(1018)  评论(2编辑  收藏  举报