Python批量实现MapBox等时圈
一、说明
最近做项目用到了等时圈,出了很多张图,准备记录一下。
做等时圈有很多种办法,一是用高德地图出行时间的API接口,原理大概是通过产生等距离栅格渔网点,计算目标点到周边渔网点的距离或时间,最后利用ArcGIS中的连接,将获得的数据和之前产生的渔网点关联起来,再以距离或时间为区分字段调整显示效果;或者将渔网点进行插值,将会产生更平滑的效果,但最终生成的等时圈都是栅格图,一是效果不好,二是计算量特别大,根据自己的精度要求和需要计算的点的数量,其需要调用API的次数是很多的,特别是高德现在更改了接口调用的限额,所以导致做起来比较麻烦。
还有一种方法是直接用ArcGIS内置的等时圈计算,需要用到路网数据,而且需要对路网数据进行处理,拓扑检查、修复等,还是比较麻烦,但是优点就是路网可以自己进行修补调整,路网精度越高,最终结果越准确,特别是针对一些小范围地块,高德、百度、OpenStreetMap等地图商没有地块内部道路数据,在这种情况下,得出的结果会更准确。
前面两种方式都有自己的优劣势,利用MapBox等时圈API接口来直接计算虽然或多或少有一定缺点,但毕竟简单省事!(MapBox也很大方,提供接口的额度都比较大,不像是某德 )
二、大概出图逻辑
由于没有提供POI点,所有数据都是以图片形式给我的,所以需要先在ArcGIS中进行地理配准(好在给我的图片带有地图,有路网信息,可以通过对照路网来进行地理配准),配准结束后需要手动矢量化信息点(好累),矢量化后利用ArcGIS中计算几何工具计算点的经纬度(注意MapBox需要WGS84坐标系),最后利用表到Excel工具将生成的点的经纬度输出到Excel表中(记得勾选....作为列标题,忘记叫什么了,反正是第一个选项,后续有空再补图),数据处理内容大致结束。
转到MapBox中,使用代码获取等时圈shp数据,大概就完成啦!

三、代码
借鉴了Python|批量获取Mapbox等时圈shapefile格式数据 - Weltㅤ - 博客园,在此基础上进行了一定程度的修改。
import time
import requests
import pandas as pd
import shapefile
from osgeo import osr
import openpyxl
import os# contours_minutes
# 文件读取路径
path = r'C:\xxxx\小型体育场_TableToExcel.xlsx'def getdata(file_name, OBJECTID, lon, lat):print('获取{}的等时圈'.format(OBJECTID))# 注意根据需要修改url中运动时间、计算方式(距离、时间)、出行形式url = 'https://api.mapbox.com/isochrone/v1/mapbox/walking/{},{}?contours_minutes=5&polygons=true&denoise=1&access_token=你的token'.format(lon, lat)try:r = requests.get(url, timeout=(3, 7)).json()# 修改文件输出路径w = shapefile.Writer('.\{}_{}.shp'.format(file_name, OBJECTID), 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=OBJECTID,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 = '.\{}_{}.prj'.format(file_name,OBJECTID)f0 = open(projfile, 'w')f0.write(wkt)f0.close()print('获取成功!')except Exception as e:print(e)if __name__ == '__main__':print('开始爬取数据')file_name = os.path.basename(path)[:-17]wb = openpyxl.load_workbook(path)# 获取当前所有的sheetsheets = wb.worksheets# 读取第一个sheet表格sheet1 = sheets[0]# 获取行数max_row_num = sheet1.max_rowmax_col_num = sheet1.max_columnfor i in range(2, max_row_num + 1):value_list = []for j in range(1, max_col_num + 1):cell = sheet1.cell(i, j).valuevalue_list.append(cell)getdata(file_name, value_list[0], value_list[1], value_list[2])time.sleep(0.5)print('All Done!!!')
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
