"等时圈"—— 一个好看又好用的东西,但想搞到这东西难度不小。看了看网上关于等时圈的制作,大多分两类:(1)通过GIS的方法,把数据导入GIS软件中进行空间分析;(2)运用JavaScript通过调用一些平台提供的API进行获取。但众所周知,我的数据库中GIS数据寥寥无几,再加上差到极致的JS,直接PASS了以上两个方法。这段时间,我在网上发现了一个网站(GEOQ,https://www.geoq.cn/login.html),只需简单的注册,就可在网站上在线绘制任意地点的等时圈,并且还可以选择不同的交通工具,设置时间参数等。故事讲到这儿,大伙儿应该明白我的想法了:自己搞不出来,爬现成的不就好啦
GEOQ界面
杭州市区汽车、电动车、步行,10min,15min,30min等时圈。
电动车等时圈
步行等时圈
汽车等时圈
以杭州市区汽车等时圈为例。通过F12抓包分析发现,等时圈数据被藏在createServiceArea这个文件中。抓包分析
点击Headers标签后,发现这是一个通过POST请求加载的数据,因此思路来了:step1:通过Python requests库模拟请求发包;step2:将json数据转为Python字典;step3:用for循环遍历获取数据,把获取的数据保存本地;step4:借助ArcGIS矢量化即可。有了思路就上手撸代码:import requestsimport jsonimport osimport openpyxlimport mathos.chdir(r"H:\Python\20200726china_pic_db\tx_house") #可以换为你自己的路径url="https://anapub.geoq.cn/service/geoqapi/createServiceArea/" #文件的URLvalues={"x":"120.55203437805177","y":"30.62823730538964","times":[30,15,10],"isRing":"false","driveType":"car"}header={ "authority": "anapub.geoq.cn", "method": "POST", "path": "/service/geoqapi/createServiceArea", "scheme": "https", "accept": "application/json, text/plain, */*", "accept-encoding": "gzip, deflate, br", "accept-language": "zh-CN,zh;q=0.9", "cache-control": "no-cache", "content-length": "92", "content-type": "application/x-www-form-urlencoded", "cookie": "JSESSIONID=340A18E3C476C24AE95CCEB797919D53; SERVERID=a4ec8211b7606cc0784c1f8ae6a6fe5e|1597125871|1597124729", "orgid": "1", "origin": "https://anapub.geoq.cn", "pragma": "no-cache", "referer": "https://anapub.geoq.cn/index.html?orgId=1&ownType=PERSONAL", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "same-origin", "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36", "x-requested-with": "XMLHttpRequest"}x_pi = 3.14159265358979324 * 3000.0 / 180.0pi = 3.1415926535897932384626 # πa = 6378245.0 # 长半轴ee = 0.00669342162296594323 # 扁率def transformlat(lng, lat): ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \ 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng)) ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lat * pi) + 40.0 * math.sin(lat / 3.0 * pi)) * 2.0 / 3.0 ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 * math.sin(lat * pi / 30.0)) * 2.0 / 3.0 return ret def transformlng(lng, lat): ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \ 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng)) ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 * math.sin(2.0 * lng * pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lng * pi) + 40.0 * math.sin(lng / 3.0 * pi)) * 2.0 / 3.0 ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 * math.sin(lng / 30.0 * pi)) * 2.0 / 3.0 return ret def gcj_to_wgs84(lng, lat): """ GCJ02(火星坐标系)转GPS84 :param lng:火星坐标系的经度 :param lat:火星坐标系纬度 :return: """ dlat = transformlat(lng - 105.0, lat - 35.0) dlng = transformlng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * pi magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi) dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi) mglat = lat + dlat mglng = lng + dlng return [lng * 2 - mglng, lat * 2 - mglat]wb=openpyxl.Workbook()respone=requests.request("POST",url,data=values,headers=header)datas=respone.textdictdatas=json.loads(datas)for jj in range(0,3): data_0=dictdatas["result"]["features"][jj]["geometry"]["rings"][0] ws=wb.create_sheet(index=jj,title=str(jj)) for ii in range(0,len(data_0)): wgs84=gcj_to_wgs84(float(data_0[ii][0]),float(data_0[ii][1])) ws.cell(row=ii+1,column=1,value=float(wgs84[0])) ws.cell(row=ii+1,column=2,value=float(wgs84[1]))wb.save("times_tx1_wgs.xlsx")
其中获取的数据为高德火星坐标,代码中将火星坐标转为了WGS84后再保存。POST请求中header参数必须要有,且准确!!!可以将headers标签中Requests.header转为字典格式传入。values参数为header标签中Form_Data转为字典格式传入。
header参数
values参数
最终抓取的结果保存为Excel。 数据保存为excel保存到本地后,想怎么玩就怎么玩,ArcGIS进行空间分析也好,和其他的POI进行叠加分析也好。所谓“数据在手,天下我有!”