arcgis公里坐标转经纬度_高德api交通态势爬取及可视化利用 python+arcgis
近日做項目,有一部分要分析研究范圍內的交通運行情況。傳統的方法是要去現場調研數車,通過交通量和道路通行能力來計算道路的服務水平。但是因為疫情原因,不想外出,想要利用其它方法來獲得區域的交通運行水平。首先想到的就是高德地圖api的交通態勢。
高德地圖api 交通態勢有了想法之后,作為一個只會看,不會寫代碼的辣雞交通規劃師,就必須借助度娘的幫助了。在網上發現很多介紹高德api交通態勢爬取的方法,下面就列舉一個我看完之后能夠實現的方法。(寫這篇文章的原因主要是為自己加深印象,小伙伴們也可以去網上搜索,很容易獲得方法和代碼)
本次使用的工具
Spyder(python3.7)編輯器、arcgis10.2主要是這兩個。(當然會用到記事本、excel之類的了)
主要思路
根據高德api提供的接口,利用python的requests庫get到高德返回到交通運行信息。將其保存成csv文件,導入到arcgis中,進行可視化展示分析。
方法分析
高德提供了兩種獲取區域交通態勢的方法,一種是矩形區域查詢(需要矩形的左下角和右上角經緯度坐標,注意是高德經緯度格式),另一種方法是圓形區域查詢(需要圓形中心的經緯度和半徑)。本次就采用了矩形區域的交通態勢查詢,但是高德對于查詢的區域范圍進行了限制(矩形對角線的距離在10公里之內),但是這也難不住網上的各位大神,利用網格的方法突破了這種限制。
將要分析的區域分割成多個網格,每個網格對角線距離不要超過10公里,然后利用for循環對網格的數據依次進行調用,這樣雖然增加api調取的次數,但也不失為一個好的方法。
方格畫的不規則,大家不要介意了,主要是示意主要代碼
代碼主要來源于網上,不是本人撰寫(主要是自己太笨),部分有所改動,經過我的實踐,代碼好用。下面這些代碼主要是用來爬取及保存交通態勢數據。
# -*- coding: utf-8 -*- """ Created on Thu May 7 10:43:18 2020@author: user """import requests import pandas as pd import json import time#初始API的URL url="https://restapi.amap.com/v3/traffic/status/rectangle?key=申請的ak&extensions=all&rectangle="#設定整個網格左下角坐標的經緯度值 baselng=120.320805 baselat=36.098401 #設定每個網格單元的經緯度寬 widthlng=0.04 #同一維度,lng=0.01≈1000米 widthlat=0.03 #同一經度,lat=0.01≈1113米 #用于儲存數據 x=[] #用于標識交通態勢線段 num=0#爬取過程可能會出錯中斷,因此增加異常處理 try:#循環每個網格進行數據爬取,在這里構建了3X3網格for i in range(0,3):#設定網格單元的左下與右上坐標的緯度值#在這里對數據進行處理,使之保留6位小數(不保留可能會莫名其妙出錯)startlat=round(baselat+i*widthlat,6)endlat=round(startlat+widthlat,6)for j in range(0,3):#設定網格單元的左下與右上坐標的經度值startlng=round(baselng+j*widthlng,6)endlng=round(startlng+widthlng,6)#設置API的URL并進行輸出測試locStr=str(startlng)+","+str(startlat)+";"+str(endlng)+","+str(endlat)thisUrl=url+locStrprint(thisUrl)#爬取數據data=requests.get(thisUrl)s=data.json()a=s["trafficinfo"]["roads"]#注意,提取數值需要使用XXX.get()的方式來實現,如a[k].get('speed')#若使用a[k]['speed']來提取,或會導致KeyError錯誤for k in range(0,len(a)):s2=a[k]["polyline"]s3=s2.split(";")for l in range(0,len(s3)):s4=s3[l].split(",")x.append([a[k].get('name'),a[k].get('status'),a[k].get('speed'),num,float(s4[0]),float(s4[1])])num=num+1time.sleep(0.1)#若爬取網格較多,可使用time.sleep(秒數)來避免高德的單秒API調用次數的限制 except Exception as e:pass#將數據結構化存儲至規定目錄的CSV文件中 c = pd.DataFrame(x,columns=['name','status','speed','roadID','x','y']) c.to_csv('C:/Users/user/Desktop/panchong/交通態勢/traffic.csv',encoding='utf-8-sig')得到的數據主要包括6列,分別是道路名稱、道路運行狀態、運行速度、道路編號、道路點x坐標,道路點y坐標。
得到的數據格式但是要注意的是返回的道路坐標是高德坐標也就是gcj02坐標,并不是我們常用的wgs_84坐標,因此要想導入進arcgis中展示,還需要進行坐標轉換。下面這些代碼,就是將gcj02轉wgs_84。經過我的實踐,好用。
# -*- coding: utf-8 -*- """ Created on Thu May 7 11:22:31 2020@author: user """#1.導入庫 # -*- coding: utf-8 -*-import jsonimport urllibimport mathimport pandas as pd import numpy as npx_pi = 3.14159265358979324 * 3000.0 / 180.0pi = 3.1415926535897932384626 # πa = 6378245.0 # 長半軸ee = 0.00669342162296594323 # 偏心率平方def gcj02_to_wgs84(lng, lat):"""GCJ02(火星坐標系)轉GPS84:param lng:火星坐標系的經度:param lat:火星坐標系緯度:return:"""if out_of_china(lng, lat):return [lng, lat]dlat = _transformlat(lng - 105.0, lat - 35.0)dlng = _transformlng(lng - 105.0, lat - 35.0)radlat = lat / 180.0 * pimagic = math.sin(radlat)magic = 1 - ee * magic * magicsqrtmagic = 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 + dlatmglng = lng + dlngreturn [lng * 2 - mglng, lat * 2 - mglat]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.0ret += (20.0 * math.sin(lat * pi) + 40.0 *math.sin(lat / 3.0 * pi)) * 2.0 / 3.0ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *math.sin(lat * pi / 30.0)) * 2.0 / 3.0return retdef _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.0ret += (20.0 * math.sin(lng * pi) + 40.0 *math.sin(lng / 3.0 * pi)) * 2.0 / 3.0ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *math.sin(lng / 30.0 * pi)) * 2.0 / 3.0return retdef out_of_china(lng, lat):"""判斷是否在國內,不在國內不做偏移:param lng::param lat::return:"""return not (lng > 73.66 and lng < 135.05 and lat > 3.86 and lat < 53.55)#2.點坐標轉換 z=[] st=pd.read_csv('C:/Users/user/Desktop/panchong/交通態勢/traffic.csv') for i in range(0,len(st)):lng=st['x'][i]lat=st['y'][i]z.append(gcj02_to_wgs84(lng,lat)) D=pd.DataFrame(z) st['x84']=D[0] st['y84']=D[1] st.to_csv('C:/Users/user/Desktop/panchong/交通態勢/tr84.csv')得到數據最后兩列就是道路的wgs_84坐標。
數據最后兩列就是轉換得到的wgs_84坐標可視化分析
1、打開Arcmap,在右側的catlog(目錄)中找到爬取的CSV文件直接拖入左側的內容列表中,如圖:
2、右鍵點擊該CSV數據,選擇“顯示XY數據”:
3、在彈出的設置框中,進行如下設置:
4、接下來的一步十分重要,打開生成要素的屬性表可以發現,屬性表并沒有FID(objectID)字段,若無該字段,該點要素將無法轉換為線要素,因此需要將該要素導出為SHP文件,方法是右鍵單擊該要素,選擇數據->導出數據,如下圖:
5、接下來是將交通態勢點轉換為線,在toolbox中找到“點集轉線”工具(數據管理工具->要素->點集轉線),在彈出的設置界面進行如下設置:
注意線字段選擇roadID(即代碼中的num變量),排序字段選擇FID。
6、等待片刻,完整的路網呈現在眼前:
看到了路網是不是一陣狂喜,但是打開屬性表,似乎笑不出來了,原來的交通態勢屬性去哪了?
不要著急,接下來一步,將屬性完美的找回來。
7、右鍵路網數據,選擇連接和關聯->連接,如下圖:
在彈出的設置框中進行如下設置:
第二個選項可以是原始的CSV表,也可以是用來轉線的點文件(即本文的dian.shp),點擊確定,再打開屬性表,屬性是不是回來了呢?
8、分級渲染可視化一下
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的arcgis公里坐标转经纬度_高德api交通态势爬取及可视化利用 python+arcgis的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java怎么把随机数放入数组_Java学
- 下一篇: 为什么手机网速太慢_为什么手机信号满格,