生活随笔
收集整理的這篇文章主要介紹了
省市区三级行政区数据获取和GeoJson地图下载
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1.背景
- 2.行政區(qū)域數據獲取
- 3.獲取GeoJson數據
1.背景
項目中用到省市區(qū)三級的行政區(qū)劃的選擇,在網上找到的數據與最新的行政區(qū)域劃分不一致,也難以確認數據的完成性。
基于echarts完成數據地區(qū)分布圖時,需要提供地區(qū)對應的geoJson格式地圖。
2.行政區(qū)域數據獲取
高德開放平臺提供了豐富數據API,其中行政區(qū)域信息可通過以下接口:
https://restapi.amap.com/v3/config/district?keywords=中國&subdistrict=3&key=5b138cc729f37d29702ff904ca9cedeb
接口獲取的數據是按照行政等級多層嵌套,為了方便后續(xù)操作,將數據轉化為了List。
以下代碼將行政區(qū)劃轉化為List并添加了id和parent_id,同時保存為json數組(area_dict.json)和MySQL數據庫腳本(area_dict.sql)。
"""
Author: Gray Snail
Date: 2020-06-30最新行政區(qū)劃獲取
基于高德地圖API獲取數據
https://restapi.amap.com/v3/config/district?keywords=中國&subdistrict=3&key=5b138cc729f37d29702ff904ca9cedeb"""
import json
import requests
def parse_district(districtObj
: dict, idx
=1, parent_id
=0):res
= []if 'name' in districtObj
.keys
():if districtObj
['level'] == 'street':return reslng
, lat
= districtCenter
(districtObj
['center'])level
= districtLevel
(districtObj
['level'])citycode
= districtObj
['citycode'] if isinstance(districtObj
['citycode'], str) else ''item
= {'id' : idx
,'adcode' : districtObj
['adcode'],'name' : districtObj
['name'],'level' : level
,'citycode' : citycode
,'lng' : lng
,'lat' : lat
,'parent_id' : parent_id
}res
.append
(item
)parent_id
= idxidx
= idx
+ 1if isinstance(districtObj
.get
('districts'), list) and len(districtObj
['districts']) > 0:for subitem
in districtObj
['districts']:subs
= parse_district
(subitem
, idx
, parent_id
)res
+= subsidx
+= len(subs
)return res
def districtLevel(levelStr
):map_val
= {'country': 0,'province': 1,'city': 2,'district': 3}return map_val
[levelStr
]def districtCenter(center
):items
= center
.split
(',')return float(items
[0]), float(items
[1])
def saveJson(data
):with open('area_dict.json', 'w', encoding
='utf-8') as fp
:json
.dump
(data
, fp
, ensure_ascii
=False, indent
=4)print('Save json file: area_dict.json')
def saveSqlFile(data
, includeCreate
=True):createCode
= """
CREATE TABLE `area_dict` (`area_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '地區(qū)Id',`area_code` char(6) NOT NULL COMMENT '地區(qū)編碼',`area_name` varchar(20) NOT NULL COMMENT '地區(qū)名',`level` tinyint(1) NOT NULL DEFAULT '0' COMMENT '地區(qū)級別(1:省份province,2:市city,3:區(qū)縣district,4:街道street)',`city_code` char(4) DEFAULT NULL COMMENT '城市編碼',`lng` int(11) DEFAULT '0' COMMENT '城市中心經度',`lat` int(11) DEFAULT '0' COMMENT '城市中心緯度',`parent_id` int(11) NOT NULL DEFAULT '-1' COMMENT '地區(qū)父節(jié)點',PRIMARY KEY (`area_id`),KEY `areaCode` (`area_code`),KEY `parentId` (`parent_id`),KEY `level` (`level`),KEY `areaName` (`area_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3261 DEFAULT CHARSET=utf8 COMMENT='地區(qū)碼表';
"""with open('area_dict.sql', 'w', encoding
='utf-8') as fp
:if includeCreate
:fp
.write
(createCode
)for item
in data
:item
['lng'] = int(item
['lng'] * 1e6)item
['lat'] = int(item
['lat'] * 1e6)sql
= "INSERT INTO area_dict(`area_id`,`area_code`,`area_name`,`level`,`city_code`,`lng`,`lat`,`parent_id`) " + \
"VALUES({id},'{adcode}','{name}',{level},'{citycode}',{lng},{lat},{parent_id});\n".format(**item
)fp
.write
(sql
)print('Save sql file: area_dict.sql')if __name__
== "__main__":url
= 'https://restapi.amap.com/v3/config/district?keywords=中國&subdistrict=3&key=5b138cc729f37d29702ff904ca9cedeb'response
= requests
.get
(url
)if response
.ok
and response
.status_code
== 200:data
= response
.json
()data
= parse_district
(data
)print('Download data successful, total:{0}!'.format(len(data
)))saveJson
(data
)saveSqlFile
(data
)else:print('Request error!')
3.獲取GeoJson數據
數據來源:基于阿里云datav,數據文件以地區(qū)編碼命名。
根據行政區(qū)域數據中保存的area_dict.json自動下載對應GeoJson文件。
行政區(qū)劃的更新,兩個平臺的數據可能存在差異,即同一地區(qū)有著不同的地區(qū)編碼,導致對應地區(qū)的地圖無法下載。代碼中errorCodes記錄了未成功下載的地區(qū)編碼。2020.07.01,未下載成功的不到30條。
"""
Author: Gray Snail
Date: 2020-06-30GeoJson地圖數據下載
基于阿里云datav
http://datav.aliyun.com/tools/atlas
"""
import requests
import json
import os
def loadDistrict(filename
):data
= []with open(filename
, 'r', encoding
='utf-8') as fp
:data
= json
.load
(fp
)return data
def saveGeoJson(areaCode
, force
=False):saveName
= 'geo/{0}.json'.format(areaCode
)if not force
and os
.path
.isfile
(saveName
):return None baseUrl
= 'https://geo.datav.aliyun.com/areas_v2/bound/{0}_full.json'baseUrl2
= 'https://geo.datav.aliyun.com/areas_v2/bound/{0}.json'if areaCode
[-2:] == '00':url
= baseUrl
.format(areaCode
)else:url
= baseUrl2
.format(areaCode
)print(url
)response
= requests
.get
(url
)if response
.ok
and response
.status_code
== 200:res_json
= response
.json
()with open(saveName
, 'w', encoding
='utf-8') as fp
:json
.dump
(res_json
, fp
, ensure_ascii
=False)else:return areaCode
if __name__
== "__main__":districts
= loadDistrict
('area_dict.json')errorCodes
= []for district
in districts
:code
= saveGeoJson
(district
['adcode'])if not code
is None:errorCodes
.append
(code
)print(errorCodes
)
總結
以上是生活随笔為你收集整理的省市区三级行政区数据获取和GeoJson地图下载的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。