欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-07 17:46:23
在做GIS的过程中,我发现很多的地图API下载下来的全国地图只精确到省一级,有时我们需要的是县市级精度,所以本文通过遍历下载各个省份的县市json文件然后再组合起来。话不多说,直接上代码:实现如下代码,你应该保证你的解释器含有geopandas、requests、json、matplotlib、pandas库。首先建立单一省份json文件的下载,区划代码中包含_full的表示它包括了县市的边界#######################单独下载部分######################impo...

在做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',
        '*' : '650000', '*_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',
            '*_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底图的自动下载
可以看到所有省份的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. *_full.json
文件名:32. xizang_full.json
文件名:33. yunnan_full.json
文件名:34. zhejaing_full.json
-------------------正在读取-------------------
-------------------读取完毕-------------------
读取地址为: D:/Desktop/test/
导出成功!保存地址为: D:/Desktop/test/mymap

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

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

运行结果:

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

本文地址:https://blog.csdn.net/qq_44638724/article/details/107133568