之前的博客中介绍到利用区县级shp转市级shp的方法Arcgis制作全国行政区(精确到县级),但实际操作起来还是比较麻烦的,并且部分省份没有BOUA文件。今天,分享另外一个方法,利用Python迅速获取全国市县级单元的Shapefile文件。
一、矢量数据文件下载
这里推荐两个网站,一个是高德地图的区划矢量数据高德地区API,另外一个是阿里云的区划矢量数据阿里云矢量数据,如下图所示(左图为高德,右图为阿里云)


不难看出,高德地图中的重庆市是没有各个区县单元的(其他直辖市也都没有),而阿里云中是含有各个区县单元。此外,高德地图的精度要高于阿里云。
注:若阿里云旁边没有下载按钮,可以按照如下方式自行创建json文件
以下载宣城市数据为例
1. 复制红框中第一条或第二条网址,用浏览器打开
访问API结果如下:
2. 复制网址中全部内容,放入自行创建的json文件中。(可以先自行创建txt文件,复制完内容后,直接更改后缀名即可变为json文件)
个人推荐:如果需要直辖市的区县数据可以使用阿里云的区划数据,其他省份的用高德地图会精确一点。
两个网站最终下载下来都是json类型的矢量数据文件(高德是geojson)
二、获取市级行政单元Shapefile
这里借助python中强大的空间分析库geopandas即可将geojson文件转为shapefile文件。但是geopandas库安装起来还是比较麻烦的!(直接pip会报错,它依赖于这四个库gdal、Shapely、Fiona、pyproj,详细安装流程可参考geopandas安装心得
安装完成后,在python中执行以下命令即可输出得到shapefile
import geopandas
import os
os.chdir('C:/Users/dell/Desktop/') #工作路径转为桌面
def saveShapefile(file_name,output_shapefile_name):
try:
data = geopandas.read_file(file_name)
localPath = str(output_shapefile_name)
data.to_file(localPath, driver='ESRI Shapefile', encoding='gbk')
print("转化成功,文件存放位置:"+localPath)
except:
print("转化失败")
saveShapefile('安徽省.geojson','Anhui_province')
当然,不借助geopandas,利用其他在线工具也可以将json文件转为shapefile文件,但生成的dbf文件可能会乱码!(因为dbf文件需要gbk编码格式才能正常显示中文)
最终生成文件如下左图所示,dbf文件内容(可正常显示)如右图所示:


三、获取县级行政单元Shapefile(2021.2.16更新)
基本思想为:先获取所有区县的json文件,再将其转为Shapefile文件。以山东省为例,基本步骤如下所示
1. 进入阿里云矢量数据网站,复制山东省的矢量数据API,如下图所示:
注:有些省份两个API都能用,有些省份可能第一条API放入如下代码中会报错,尽量复制第二条API
2. 执行下述代码,即可得到山东省所有区县的json文件
import requests
import json
import re
import os
os.chdir('c:/users/dell/Desktop/')
def get_data(url):
r = requests.get(url)
data = r.json()['features']
return data
def get_json(url,file_name):
pattern = '\d+'
output = {"type": "FeatureCollection",
"features":[]}
data = get_data(url)
with open(file_name,'w') as f:
for city in data:
city_code = city['properties']['adcode']
url = re.sub(pattern,str(city_code),url)
city_data = get_data(url)
if city_data:
output['features'].extend(city_data)
print(city['properties']['name']+'下所有区县保存完毕')
else: #考虑部分省份存在市级单元以下无县级单元
new_url = 'https://geo.datav.aliyun.com/areas/bound/geojson?code=' + str(city_code)
other_data = get_data(new_url)
output['features'].extend(other_data)
print(city['properties']['name']+'已为最小行政单元,保存完毕')
json.dump(output,f,indent=4)
if __name__=='__main__':
url = 'https://geo.datav.aliyun.com/areas/bound/geojson?code=370000_full' #复制的API
get_json(url,'山东省.json')
部分结果如下所示:
3. 转化Shapefile,此部分代码与市级转化基本一致
import geopandas
def saveShapefile(file_name,output_shapefile_name):
try:
data = geopandas.read_file(file_name)
localPath = str(output_shapefile_name)
data.to_file(localPath, driver='ESRI Shapefile', encoding='gbk')
print("转化成功,文件存放位置:"+localPath)
except Exception as e:
print(e)
saveShapefile('山东省.json','ShanDong_province')
在Geoda中加载生成的Shapefile文件,如下图所示:
注意:阿里云矢量数据还是比较新的(目前更新于2020年4月),部分省份的县级行政单元个数可能与全国地理基础信息网存在出入!!!
以上就是本次分享的全部内容~