您現在的位置是:首頁 > 動作武俠首頁動作武俠

Python+ArcGIS應用 獲取天地圖行政區劃資料 !

  • 由 菜鳥帶你學程式設計 發表于 動作武俠
  • 2021-08-11
簡介postStr={“searchWord”:“中國”,“searchType”:“1”,“needSubInfo”:“true”,“needAll”:“true”,“needPolygon”:“false”,“needPre”:“true”

奧維地圖天地圖金鑰怎麼輸入

在上一篇文章中,提到天地圖有提供行政區劃的API,可以利用此API來獲取行政區劃資料,下面我們來看看怎麼獲取天地圖的行政區劃資料,並轉為GIS格式。天地圖行政區劃API地址:http://lbs。tianditu。gov。cn/server/administrative。html

介面分析

首先是申請金鑰(2019年後天地圖的服務都需要使用金鑰),比較簡單,根據提示註冊即可。

然後是分析介面,上述地址中有提供行政區劃請求示例: http://api。tianditu。gov。cn/administrative?postStr={“searchWord”:“北京”,“searchType”:“1”,“needSubInfo”:“false”,“needAll”:“false”,“needPolygon”:“true”,“needPre”:“true”}&tk=您的金鑰

以及說明

歡迎大家加入小編建立的Python行業交流群,有大牛答疑,有資源共享,有企業招人!是一個非常不錯的交流基地!群號:683380553

Python+ArcGIS應用 獲取天地圖行政區劃資料 !

經分析,將searchWord引數設為“中國”,needSubInfo引數為true,needAll引數為true則可以獲取全國區縣級的行政區劃資料。由於請求比較久,所以這裡先將 needAll引數設為false測試一波,地址為:http://api。tianditu。gov。cn/administrative?postStr={“searchWord”:“中國”,“searchType”:“1”,“needSubInfo”:“true”,“needAll”:“false”,“needPolygon”:“true”,“needPre”:“true”}&tk=金鑰

返回結果即省級行政區劃。根據上一篇的經驗,將返回的結果解析再儲存到文字中,然後利用arcpy生成shp檔案。

資料獲取

#資料獲取及儲存

url=‘http://api。tianditu。gov。cn/administrative?postStr={“searchWord”:“中國”,“searchType”:“1”,“needSubInfo”:“true”,“needAll”:“false”,“needPolygon”:“true”,“needPre”:“true”}&tk=金鑰’res = requests。get(url)data = json。loads(res。text)geo=[]num=len(data[“data”][0][“child”]) #計算有多少個省的資料,34個for i in range(num): Pname=data[“data”][0][“child”][i][“name”] print(Pname) num2=len(data[“data”][0][“child”][i][“points”]) #有些省份存在多個面的情況 for k in range(num2): polygon=data[“data”][0][“child”][i][“points”][k][“region”]。split(“,”) #每個面的座標 for j in range(len(polygon)): X=polygon[j]。split(“ ”)[0] Y=polygon[j]。split(“ ”)[1] geo。append([j,X,Y,Pname])coor = pd。DataFrame(geo)coor。to_csv(r“D:\study\spider\座標\Tchina。csv”, mode=‘a’,header=None,index=False,encoding=‘gb2312’) #不要表頭和列編號

這就獲取到了中國省份行政區劃的座標點,發現座標是經緯度的,但是小數位卻只有三位,這精度對於不太規則的行政區劃面狀資料來說肯定不夠,還容易會有座標點重複的問題(對於經緯度座標,小數位一般都需要6位以上),先試著生成看看。

Python+ArcGIS應用 獲取天地圖行政區劃資料 !

資料處理

這裡還是利用上一篇中的程式碼

#資料處理,xy生成面並賦值

import os,sys,arcpy#解析座標檔案coordList=[]polygonCoordList=[]startX,startY=0。0,0。0with open(‘。/座標/Tchina。csv’, ‘r’) as f: rows = f。readlines() for row in rows: M,X,Y= map(lambda x: float(x), row。split(“,”)[0:3]) City=row。split(“,”)[3]。decode(‘gbk’) if M==0: startX, startY = X, Y polygonCoordList。append([X, Y,City]) continue if startX != X and startY != Y: polygonCoordList。append([X, Y,City]) else: coordList。append(polygonCoordList) polygonCoordList = [] print(‘面數:%d’ %(len(coordList))) #生成多邊形feature_class = arcpy。CreateFeatureclass_management(r“D:\study\spider\座標”, “Tchina。shp”, “Polygon”)arcpy。AddField_management(r“D:\study\spider\座標\Tchina。shp”, “name”, “TEXT”)point=arcpy。Point()array=arcpy。Array()n=0for polygon in coordList: with arcpy。da。InsertCursor(feature_class, [“SHAPE@”, ‘name’]) as cursor: try: for coordPair in polygon: point。X = coordPair[0] point。Y = coordPair[1] name = coordPair[2] array。add(point) array。add(array。getObject(0)) polygongeo = arcpy。Polygon(array) cursor。insertRow([polygongeo, name]) array。removeAll() # 移除,以免累加面 n += 1 except: pass continue del cursor

執行中確實有問題, arcgis在生成面的時候,如果兩個點之間太接近的話會報錯,這裡是使用try…except來將報錯的面跳過的方式來處理。生成的結果如下圖:

Python+ArcGIS應用 獲取天地圖行政區劃資料 !

結果分析

這裡其實有些小島的面已經被刪除了。而且精度和百度地圖上的差不多,面的轉折太生硬,也只能用來做做展示。

再次分析介面,發現這個請求還可以返回行政區劃對應的點資料(好像是政府駐地),如果只需要各個區縣的點,這個方法還是可以的,返回的資料相對準確,精度也夠。就是返回的資料結構不是很清晰,因為不是所有的行政區劃都是省、市、區縣的結構,所以資料清洗上有點麻煩,大家可以試一試。地址:http://api。tianditu。gov。cn/administrative?postStr={“searchWord”:“中國”,“searchType”:“1”,“needSubInfo”:“true”,“needAll”:“true”,“needPolygon”:“false”,“needPre”:“true”}&tk=金鑰

要獲取全國區縣級行政區劃資料,利用上述方式好像也行不通,那就再試試 使用上篇文章中搜索返回座標串的方法,在天地圖線上地圖上試試。地址:http://map。tianditu。gov。cn/

在搜尋框中輸入“福田”,也會範圍相應的範圍,而且返回的座標點小數位也夠,所以也能使用上篇的方法來獲取範圍的座標點,不過面的精度也一般。本著搞都搞了,沒點成果好像說不過去的想法,那就搞一搞全國市級行政區劃的資料。

分析請求可知請求的地址為:http://api。tianditu。gov。cn/search?postStr={“yingjiType”:0,“sourceType”:0,“keyWord”:“深圳市”,“level”:11,“mapBound”:“113。46062,22。46624,114。39789,23。00833”,“queryType”:1,“start”:0,“count”:10,“queryTerminal”:10000}&type=query&tk=2ce94f67e58faa24beb7cb8a09780552

keyWord引數為查詢關鍵字,mapBound引數為該區域範圍,經過測試該引數不會影響返回結果,這裡的tk是自帶的搜尋金鑰,所以只需要關心keyWord引數。這樣就可以構建請求,然後解析資料,儲存為文字格式。這裡的城市名稱也是用上篇在 百度web服務api逆地理編資源頁下面的,建議從天地圖中提取,會更準確些。

#獲取資料及儲存

with open(‘中國市級城市。txt’, ‘r’, encoding=‘gbk’) as f: citys = f。readlines() for city in citys: cityName=city。split(‘,’)[0]。strip() print(cityName) url=‘http://api。tianditu。gov。cn/search?postStr={“yingjiType”:0,“sourceType”:0,“keyWord”:“%s”,“level”:11,“mapBound”:“113。46062,22。46624,114。39789,23。00833”,“queryType”:1,“start”:0,“count”:10,“queryTerminal”:10000}&type=query&tk=2ce94f67e58faa24beb7cb8a09780552’ %(cityName) res = requests。get(url) data = json。loads(res。text)[“area”] geo=[] num = len(data[“points”]) # 存在多個面的情況 for i in range(num): polygon = data[“points”][i][“region”]。split(“,”) # 每個面的座標 for j in range(len(polygon)): X = polygon[j]。split(“ ”)[0] Y = polygon[j]。split(“ ”)[1] geo。append([j, X, Y, cityName]) coor = pd。DataFrame(geo) coor。to_csv(r“D:\study\spider\座標\tdt中國市級。csv”, mode=‘a’,header=None,index=False,encoding=‘gb2312’) #不要表頭和列編號

由於儲存的座標格式都是一致的,所以資料處理的程式碼都是一樣的,這裡就不重複說明了。生成的結果有個別面有問題,如呼和浩特市返回的資料是旁邊烏蘭察布市的範圍,所以這兩個市的範圍面重疊而且有個面空了(已反饋,不知道有沒有獎),經過簡單處理後,看下結果:

Python+ArcGIS應用 獲取天地圖行政區劃資料 !

精度比百度地圖還是要稍微高一點,起碼基本返回了範圍面,這個結果用於一般地圖展示還是可以的,對於有高要求的就不太行了。不過區縣級行政區劃資料,屬於機密等級,網上能獲取到的資料精度不高還是可以理解,精度要求高的還是需要透過專案從對應部門獲取,同時也可以看出要做到這一級別的資料公開還是有很長的路要走。

Top