在做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中检验文件是否完整可用: 导入成功,接下来进行投影转换,让地图符合国家测绘标准: 别忘记加上九段线和南海诸岛以保持领土的完整性:
