通过Python实现shp底图的自动下载

在做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

通过Python实现shp底图的自动下载_第1张图片
可以看到所有省份的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

通过Python实现shp底图的自动下载_第2张图片
可以看到刚才的test文件中就生成了ArcGIS可以直接使用的shp文件了,为了检验一下效果如何,我们通过geopandas库画出我们转换的结果

map = gpd.read_file('D:/Desktop/test/mymap.shp')
map.plot()

运行结果:

通过Python实现shp底图的自动下载_第3张图片
可以看到包括了县市级边界的完整中国地图被绘制出来了,同样我们也可以到ArcGIS中检验文件是否完整可用:
通过Python实现shp底图的自动下载_第4张图片
导入成功,接下来进行投影转换,让地图符合国家测绘标准:
通过Python实现shp底图的自动下载_第5张图片
别忘记加上九段线和南海诸岛以保持领土的完整性:
通过Python实现shp底图的自动下载_第6张图片

你可能感兴趣的:(GIS,json,python)