高德地图WEB服务API提供了很多实用的Web接口,申请完高德地图key(详见获取key),就可以使用。本篇博文介绍的行政区划境界线下载,使用的是行政区划查询这个接口,接口访问url如下:
https://restapi.amap.com/v3/config/district?key=申请的key&keywords=$&subdistrict=0&extensions=all
下面对这个接口的关键参数进行简单说明:
(1)keywords:查询关键字,支持 行政区名称、citycode、adcode,adcode信息可参考城市编码表;
(2)subdistrict:子级行政区,设置显示下级行政区级数(行政区级别包括:国家、省/直辖市、市、区/县、乡镇/街道多级数据),可选值:0、1、2、3等数字,并以此类推,含义如下:
0:不返回下级行政区;
1:返回下一级行政区;
2:返回下两级行政区;
3:返回下三级行政区;
特别说明:因需要获取的是境界线数据,即使设置返回下级行政区,返回的也只是属性信息,不包含子行政区的境界线数据。
(3)extensions:此项控制行政区信息中返回行政区边界坐标点; 可选值:base、all;
base:不返回行政区边界坐标点;
all:只返回当前查询district的边界值,不返回子节点的边界值;
目前不能返回乡镇/街道级别的边界值
因此,在本例中需要设置为 all。
(1)指定抓取的区域,可为adcode,citycodes或行政区划名称;
(2)利用高德地图接口请求数据;
(3)对边界点数据进行解析,并处理成geojson格式;
解析过程中,要注意多部件的问题(即MultiPolygon的情况)。
(4)将结果保存成json格式。
下面是抓取全国省级行政区边界线并将所有数据最终处理成geojson格式并保存的代码,本例亲自编写并测试有效,数据已应用在实际项目中,需要的可直接使用。
'''
Created on 2018年12月26日
@author: QinChao
@description:请求高德地图行政区划数据
'''
adcodes = {
'110000':'北京市',
'120000':'天津市',
'130000':'河北省',
'140000':'山西省',
'150000':'内蒙古自治区',
'210000':'辽宁省',
'220000':'吉林省',
'230000':'黑龙江省',
'310000':'上海市',
'320000':'江苏省',
'330000':'浙江省',
'340000':'安徽省',
'350000':'福建省',
'360000':'江西省',
'370000':'山东省',
'410000':'河南省',
'420000':'湖北省',
'430000':'湖南省',
'440000':'广东省',
'450000':'广西壮族自治区',
'460000':'海南省',
'500000':'重庆市',
'510000':'四川省',
'520000':'贵州省',
'530000':'云南省',
'540000':'西藏自治区',
'610000':'陕西省',
'620000':'甘肃省',
'630000':'青海省',
'640000':'宁夏回族自治区',
'650000':'新疆维吾尔自治区',
'710000':'台湾省',
'810000':'香港特别行政区',
'820000':'澳门特别行政区'
,'900000':'外国'
}
url = 'https://restapi.amap.com/v3/config/district?key=申请的高德地图key&keywords=$&subdistrict=0&extensions=all'
import urllib.request
import simplejson
import json
def request_district(keyword):
print('key:', url.replace('$', keyword))
return simplejson.loads(urllib.request.urlopen(url.replace('$', keyword)).read())
def struct_feature(coords, adcodes, name):
return {
'type': 'Feature',
'geometry': {
'type': coords['type'],
'coordinates': coords['coords']
},
'properties':{
'adcodes': adcodes,
'name': name
}
}
def struct_coordinates(data):
coordinates = []
type = 'Polygon'
districts = data['districts'][0]
polyline_str = districts['polyline']
district = polyline_str.split('|')
# 由多部分构成,为多部件
if len(district) > 1:
type = 'MultiPolygon'
for part in district:
coordinate = []
coords = part.split(';')
for coord in coords:
x, y = coord.split(',')
coordinate.append([float(x), float(y)])
if len(coordinate) > 200:
coordinates.append([coordinate])
else:
coordinate = []
coords = district[0].split(';')
for coord in coords:
x, y = coord.split(',')
coordinate.append([float(x), float(y)])
coordinates.append(coordinate)
return {
'type': type,
'coords': coordinates
}
def write_content(file_path, content, file_type = 'txt', mode = 'w'):
'''
文本内容写入
file_path--- 写入文件路径
content--- 写入内容
file_type--- 文件格式, 默认为txt, 其他包括json
mode--- 文件打开模式
'''
with open(file_path, mode) as f:
if file_type == 'txt':
f.writelines(content)
elif file_type == 'json':
json.dump(content, f)
f.flush()
f.close()
if __name__ == "__main__":
province_geojson = {
'type': 'FeatureCollection',
'features': []
}
for adcode in adcodes.keys():
print('adcode:', adcode)
src_data = request_district(adcode)
coordinates = struct_coordinates(src_data)
feature = struct_feature(coordinates, adcode, adcodes[adcode])
province_geojson['features'].append(feature)
write_content('G:/heze.json', province_geojson, 'json')