在做GIS的过程中,我发现很多的地图API下载下来的全国地图只精确到省一级,有时我们需要的是县市级精度,所以本文通过遍历下载各个省份的县市json文件然后再组合起来。话不多说,直接上代码:
实现如下代码,你应该保证你的解释器含有geopandas、requests、json、matplotlib、pandas库。首先建立单一省份json文件的下载,区划代码中包含_full的表示它包括了县市的边界
#######################单独下载部分######################
import json #用于解析json
import requests #用于处理url
# 省名 省code 省名(含市) 省code(含市)
dict = {
'beijing' : '110000', 'beijing_full' : '110000_full',
'tianjing' : '120000', 'tianjing_full' : '120000_full',
'hebei' : '130000', 'hebei_full' : '130000_full',
'shanxi' : '140000', 'shanxi_full' : '140000_full',
'neimenggu': '150000', 'neimenggu_full' : '150000_full',
'liaoning' : '210000', 'liaoning_full' : '210000_full',
'jilin' : '220000', 'jilin_full' : '220000_full',
'heilongjiang' : '230000', 'heilongjiang_full' : '230000_full',
'shanghai' : '310000', 'shanghai_full' : '310000_full',
'jiangsu' : '320000', 'jiangsu_full' : '320000_full',
'zhejiang' : '330000', 'zhejaing_full' : '330000_full',
'anhui' : '340000', 'anhui_full' : '340000_full',
'fujian' : '350000', 'fujian_full' : '350000_full',
'jiangxi' : '360000', 'jiangxi_full' : '360000_full',
'shandong' : '370000', 'shandong_full' : '370000_full',
'hennan' : '410000', 'henan_full' : '410000_full',
'hubei' : '420000', 'hubei_full' : '420000_full',
'hunan' : '430000', 'hunan_full' : '430000_full',
'guangdong': '440000', 'guangdong_full' : '440000_full',
'guangxi' : '450000', 'guangxi_full' : '450000_full',
'hainan' : '460000', 'hainan_full' : '460000_full',
'chongqing': '500000', 'chongqing_full' : '500000_full',
'sichuan' : '510000', 'sichuan_full' : '510000_full',
'guizhou' : '520000', 'guizhou_full' : '520000_full',
'yunnan' : '530000', 'yunnan_full' : '530000_full',
'xizang' : '540000', 'xizang_full' : '540000_full',
'shaxi' : '610000', 'shaxi_full' : '610000_full',
'gansu' : '620000', 'gansu_full' : '620000_full',
'qinghai' : '630000', 'qinghai_full' : '630000_full',
'ningxia' : '640000', 'ningxia_full' : '640000_full',
'xinjiang' : '650000', 'xinjiang_full' : '650000_full',
'HK' : '810000', 'HK_full' : '810000_full',
'Mo' : '820000', 'Mo_full' : '820000_full',
'Tw' : '710000', 'Tw_full' : '710000_full',
"whole" : '100000', 'whole_full' : '100000_full',
} #建立省份与code的索引
def download_Json(name, path): #json下载函数,name是想要下载的省份,名称在dict中给出,path是保存地址
url = 'https://geo.datav.aliyun.com/areas/bound/' #定值,请勿修改
print("正在下载,地址为:", url + dict[name] + '.json') #检查下载文件名称
# 将响应信息进行json格式化
response = requests.get(url + dict[name] + '.json') #得到response对象
text = response.text #获取response对象的文本部分
json_text = json.loads(text) #解析为json格式
# 将json格式化的数据保存
Path = path + ".json" #写地址
with open(Path, 'w', encoding='utf-8') as f:
f.write(json.dumps(json_text, indent=4))
print('下载成功')
######测试######
target = 'shaxi_full' #测试下载
download_Json(target, path= 'D:/Desktop/'+ target)#第一个参数是需要下载的省份,第二个参数是文件保存的地址,
######测试######
我们只需要按照字典中给出的名称改变target的内容就可以下载任一省份的json文件
接下来将包含县市的键值对提取出来,通过遍历字典的方式下载所有省份的json文件
######################全体下载部分########################
dict1 = { 'beijing_full' : '110000_full',
'tianjing_full' : '120000_full',
'hebei_full' : '130000_full',
'shanxi_full' : '140000_full',
'neimenggu_full' : '150000_full',
'liaoning_full' : '210000_full',
'jilin_full' : '220000_full',
'heilongjiang_full' : '230000_full',
'shanghai_full' : '310000_full',
'jiangsu_full' : '320000_full',
'zhejaing_full' : '330000_full',
'anhui_full' : '340000_full',
'fujian_full' : '350000_full',
'jiangxi_full' : '360000_full',
'shandong_full' : '370000_full',
'henan_full' : '410000_full',
'hubei_full' : '420000_full',
'hunan_full' : '430000_full',
'guangdong_full' : '440000_full',
'guangxi_full' : '450000_full',
'hainan_full' : '460000_full',
'chongqing_full' : '500000_full',
'sichuan_full' : '510000_full',
'guizhou_full' : '520000_full',
'yunnan_full' : '530000_full',
'xizang_full' : '540000_full',
'shaxi_full' : '610000_full',
'gansu_full' : '620000_full',
'qinghai_full' : '630000_full',
'ningxia_full' : '640000_full',
'xinjiang_full' : '650000_full',
'HK_full' : '810000_full',
'Mo_full' : '820000_full',
'Tw_full' : '710000_full'
} #建立遍历下载索引
i = 1
for key in dict1.keys(): #遍历字典中所有的键
download_Json(key, path='D:/Desktop/test/' + key) #对每个键调用json下载函数
print('下载计数:', i)
i = i + 1
运行结果如下
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/110000_full.json
下载成功
下载计数: 1
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/120000_full.json
下载成功
下载计数: 2
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/130000_full.json
下载成功
下载计数: 3
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/140000_full.json
下载成功
下载计数: 4
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/150000_full.json
下载成功
下载计数: 5
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/210000_full.json
下载成功
下载计数: 6
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/220000_full.json
下载成功
下载计数: 7
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/230000_full.json
下载成功
下载计数: 8
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/310000_full.json
下载成功
下载计数: 9
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/320000_full.json
下载成功
下载计数: 10
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/330000_full.json
下载成功
下载计数: 11
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/340000_full.json
下载成功
下载计数: 12
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/350000_full.json
下载成功
下载计数: 13
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/360000_full.json
下载成功
下载计数: 14
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/370000_full.json
下载成功
下载计数: 15
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/410000_full.json
下载成功
下载计数: 16
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/420000_full.json
下载成功
下载计数: 17
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/430000_full.json
下载成功
下载计数: 18
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/440000_full.json
下载成功
下载计数: 19
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/450000_full.json
下载成功
下载计数: 20
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/460000_full.json
下载成功
下载计数: 21
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/500000_full.json
下载成功
下载计数: 22
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/510000_full.json
下载成功
下载计数: 23
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/520000_full.json
下载成功
下载计数: 24
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/530000_full.json
下载成功
下载计数: 25
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/540000_full.json
下载成功
下载计数: 26
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/610000_full.json
下载成功
下载计数: 27
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/620000_full.json
下载成功
下载计数: 28
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/630000_full.json
下载成功
下载计数: 29
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/640000_full.json
下载成功
下载计数: 30
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/650000_full.json
下载成功
下载计数: 31
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/810000_full.json
下载成功
下载计数: 32
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/820000_full.json
下载成功
下载计数: 33
正在下载,地址为: https://geo.datav.aliyun.com/areas/bound/710000_full.json
下载成功
下载计数: 34
可以看到所有省份的json文件都被下载下来了,但json文件是不能直接用于GIS分析的,下一步我们将json转换为ArcGIS可直接执行的shp文件,代码如下:
###########################整合下载部分#########################
import os
import time
import geopandas as gpd
import pandas as pd
import matplotlib.pyplot as plt
def get_filelist(dir): #读取文件子目录
Filelist = []
for home, dirs, files in os.walk(path):
for filename in files:
Filelist.append(os.path.join(home, filename))
print("读取地址为:", path)
return Filelist
def filename(filelist,n): #返回文件名称(可选)
if n > len(filelist):
print("文件长度错误!当前文件长度为:", len(filelist))
else:
for i in range(n):
#print("文件路径为:",filelist[i])
str = '/'
location = filelist[i].rfind(str)
name = filelist[i][location+1::]
print("文件名:{0}. {1}".format(i+1, name))
def read_map(Filelist): #读取地图数据
Mapdata = []
merge = pd.DataFrame()
print('-------------------正在读取-------------------')
for i in Filelist:
Map = gp.read_file(i)
Mapdata.append(Map)
print('-------------------读取完毕-------------------')
print('读取地址为:',path)
return Mapdata
def to_geoDataFrame(file): #将pd.DataFrame转换为gp格式
merge = pd.DataFrame()
for i in range(len(file)):
rely = pd.DataFrame(file[i])
merge = pd.concat([merge,rely],ignore_index=True)
Merge = gpd.GeoDataFrame(merge)
return Merge
def save_file(saveFile,savePath): #导出shp文件,savePath是存储地址
saveFile.to_file(savePath+'.shp',conding='utf-8')
print('导出成功!保存地址为:',savePath)
'''
if __name__ =="__main__":
Filelist = get_filelist(dir)
print(len( Filelist))
for file in Filelist :
print(file)
'''
path ='D:/Desktop/test/' #指定读取地址
Filelist = get_filelist(path) #读取地址内的所有文件
filename(Filelist,len(Filelist)) #查看读取文件的名称(可选)
Map = read_map(Filelist) #读取文件(DataFrame格式)
mergeMap = to_geoDataFrame(Map) #转换为GeoDataFrame格式
save_file(mergeMap,'D:/Desktop/test/mymap') #将转换好的地图导出并保存
运行结果:
读取地址为: D:/Desktop/test/
文件名:1. anhui_full.json
文件名:2. beijing_full.json
文件名:3. chongqing_full.json
文件名:4. fujian_full.json
文件名:5. gansu_full.json
文件名:6. guangdong_full.json
文件名:7. guangxi_full.json
文件名:8. guizhou_full.json
文件名:9. hainan_full.json
文件名:10. hebei_full.json
文件名:11. heilongjiang_full.json
文件名:12. henan_full.json
文件名:13. HK_full.json
文件名:14. hubei_full.json
文件名:15. hunan_full.json
文件名:16. jiangsu_full.json
文件名:17. jiangxi_full.json
文件名:18. jilin_full.json
文件名:19. liaoning_full.json
文件名:20. Mo_full.json
文件名:21. neimenggu_full.json
文件名:22. ningxia_full.json
文件名:23. qinghai_full.json
文件名:24. shandong_full.json
文件名:25. shanghai_full.json
文件名:26. shanxi_full.json
文件名:27. shaxi_full.json
文件名:28. sichuan_full.json
文件名:29. tianjing_full.json
文件名:30. Tw_full.json
文件名:31. xinjiang_full.json
文件名:32. xizang_full.json
文件名:33. yunnan_full.json
文件名:34. zhejaing_full.json
-------------------正在读取-------------------
-------------------读取完毕-------------------
读取地址为: D:/Desktop/test/
导出成功!保存地址为: D:/Desktop/test/mymap
可以看到刚才的test文件中就生成了ArcGIS可以直接使用的shp文件了,为了检验一下效果如何,我们通过geopandas库画出我们转换的结果
map = gpd.read_file('D:/Desktop/test/mymap.shp')
map.plot()
运行结果:
可以看到包括了县市级边界的完整中国地图被绘制出来了,同样我们也可以到ArcGIS中检验文件是否完整可用:
导入成功,接下来进行投影转换,让地图符合国家测绘标准:
别忘记加上九段线和南海诸岛以保持领土的完整性: